lớp I2C -- giao thức nối tiếp hai dây¶
I2C là giao thức hai dây dùng để giao tiếp giữa các thiết bị. Ở cấp độ vật lý, nó gồm 2 dây: SCL và SDA, lần lượt là đường xung nhịp và đường dữ liệu.
Các đối tượng I2C được tạo ra gắn với một bus cụ thể. Chúng có thể được khởi tạo khi tạo hoặc khởi tạo sau.
In đối tượng I2C sẽ cho bạn biết thông tin về cấu hình của nó.
Cả hai triển khai I2C phần cứng và phần mềm đều tồn tại thông qua các lớp I2C và SoftI2C. I2C phần cứng sử dụng hỗ trợ phần cứng cơ bản của hệ thống để thực hiện các thao tác đọc/ghi và thường hiệu quả và nhanh nhưng có thể có hạn chế về các chân (pin) có thể sử dụng. I2C phần mềm được triển khai bằng cách bit-banging và có thể sử dụng trên bất kỳ chân (pin) nào nhưng không hiệu quả bằng. Các lớp này có cùng các phương thức và khác nhau chủ yếu ở cách chúng được xây dựng.
Ghi chú
Bus I2C yêu cầu mạch kéo lên (pull-up) trên cả SDA và SCL để hoạt động. Thông thường đây là các điện trở trong khoảng 1 - 10 kOhm, kết nối từ mỗi SDA/SCL đến Vcc. Nếu không có các điện trở này, hành vi là không xác định và có thể bao gồm từ treo máy, reset watchdog bất ngờ cho đến giá trị sai. Thường mạch kéo lên này đã được tích hợp sẵn trong bo mạch MCU hoặc bo sensor, nhưng không có quy tắc cứng nhắc về điều đó. Vì vậy hãy kiểm tra khi gặp sự cố. Xem thêm hướng dẫn học tập tuyệt vời này của Adafruit về cách đấu dây I2C.
Ví dụ sử dụng:
from machine import I2C
i2c = I2C(freq=400000) # create I2C peripheral at frequency of 400kHz
# depending on the port, extra parameters may be required
# to select the peripheral and/or pins to use
i2c.scan() # scan for peripherals, returning a list of 7-bit addresses
i2c.writeto(42, b'123') # write 3 bytes to peripheral with 7-bit address 42
i2c.readfrom(42, 4) # read 4 bytes from peripheral with 7-bit address 42
i2c.readfrom_mem(42, 8, 3) # read 3 bytes from memory of peripheral 42,
# starting at memory-address 8 in the peripheral
i2c.writeto_mem(42, 2, b'\x10') # write 1 byte to memory of peripheral 42
# starting at address 2 in the peripheral
Các hàm khởi tạo¶
- class machine.I2C(id: int, *, scl: Pin | None = None, sda: Pin | None = None, freq: int = 400000, timeout: int = 50000)¶
Xây dựng và trả về một đối tượng I2C mới sử dụng các tham số sau:
id xác định một ngoại vi I2C cụ thể. Các giá trị cho phép phụ thuộc vào cổng/bo mạch cụ thể
scl phải là một đối tượng chân (pin) chỉ định chân sử dụng cho SCL.
sda phải là một đối tượng chân (pin) chỉ định chân sử dụng cho SDA.
freq phải là một số nguyên thiết lập tần số tối đa cho SCL.
timeout là thời gian tối đa tính bằng micro giây cho phép các giao dịch I2C. Tham số này không được phép trên một số cổng.
Lưu ý rằng một số cổng/bo mạch sẽ có giá trị mặc định của scl và sda có thể thay đổi trong hàm khởi tạo này. Các cổng/bo mạch khác sẽ có giá trị cố định của scl và sda không thể thay đổi.
Các phương thức chung¶
- init(scl: Pin, sda: Pin, *, freq: int = 400000) None¶
Khởi tạo bus I2C với các đối số đã cho:
scl là đối tượng chân (pin) cho đường SCL
sda là đối tượng chân (pin) cho đường SDA
freq là tốc độ xung nhịp SCL
Trong trường hợp I2C phần cứng, tần số xung nhịp thực tế có thể thấp hơn tần số yêu cầu. Điều này phụ thuộc vào phần cứng của nền tảng. Tốc độ thực tế có thể xác định bằng cách in đối tượng I2C.
Các thao tác I2C nguyên thủy¶
Các phương thức sau đây triển khai các thao tác bus điều khiển I2C nguyên thủy và có thể kết hợp để tạo bất kỳ giao dịch I2C nào. Chúng được cung cấp nếu bạn cần kiểm soát nhiều hơn đối với bus, nếu không thì có thể sử dụng các phương thức tiêu chuẩn (xem bên dưới).
Các phương thức này chỉ khả dụng trên lớp
SoftI2C.- readinto(buf: bytearray, nack: bool = True, /) None¶
Đọc các byte từ bus và lưu chúng vào buf. Số byte đọc là độ dài của buf. Một ACK sẽ được gửi trên bus sau khi nhận tất cả các byte trừ byte cuối cùng. Sau khi nhận byte cuối cùng, nếu nack là true thì một NACK sẽ được gửi, ngược lại một ACK sẽ được gửi (và trong trường hợp này thiết bị ngoại vi giả định rằng sẽ có thêm byte được đọc trong lần gọi sau).
Các thao tác bus tiêu chuẩn¶
Các phương thức sau đây triển khai các thao tác đọc và ghi điều khiển I2C tiêu chuẩn nhắm vào một thiết bị ngoại vi cụ thể.
- readfrom(addr: int, nbytes: int, stop: bool = True, /) bytes¶
Đọc nbytes từ thiết bị ngoại vi được chỉ định bởi addr. Nếu stop là true thì điều kiện STOP được tạo ra ở cuối quá trình truyền. Trả về đối tượng
bytesvới dữ liệu đã đọc.
- readfrom_into(addr: int, buf: bytearray, stop: bool = True, /) None¶
Đọc vào buf từ thiết bị ngoại vi được chỉ định bởi addr. Số byte đọc sẽ là độ dài của buf. Nếu stop là true thì điều kiện STOP được tạo ra ở cuối quá trình truyền.
Phương thức trả về
None.
- writeto(addr: int, buf: bytes, stop: bool = True, /) int¶
Ghi các byte từ buf đến thiết bị ngoại vi được chỉ định bởi addr. Nếu nhận được NACK sau khi ghi một byte từ buf thì các byte còn lại sẽ không được gửi. Nếu stop là true thì điều kiện STOP được tạo ra ở cuối quá trình truyền, ngay cả khi nhận được NACK. Hàm trả về số lượng ACK đã nhận được.
- writevto(addr: int, vector: tuple | list, stop: bool = True, /) int¶
Ghi các byte trong vector đến thiết bị ngoại vi được chỉ định bởi addr. vector phải là một tuple hoặc danh sách các đối tượng có giao thức bộ đệm. addr được gửi một lần và sau đó các byte từ mỗi đối tượng trong vector được ghi ra tuần tự. Các đối tượng trong vector có thể có độ dài bằng không, trong trường hợp đó chúng không đóng góp vào đầu ra.
Nếu nhận được NACK sau khi ghi một byte từ một trong các đối tượng trong vector thì các byte còn lại và bất kỳ đối tượng còn lại nào đều không được gửi. Nếu stop là true thì điều kiện STOP được tạo ra ở cuối quá trình truyền, ngay cả khi nhận được NACK. Hàm trả về số lượng ACK đã nhận được.
Các thao tác bộ nhớ¶
Một số thiết bị I2C hoạt động như thiết bị bộ nhớ (hoặc tập hợp các thanh ghi) có thể đọc và ghi. Trong trường hợp này có hai địa chỉ liên quan đến giao dịch I2C: địa chỉ ngoại vi và địa chỉ bộ nhớ. Các phương thức sau đây là các hàm tiện ích để giao tiếp với các thiết bị như vậy.
- readfrom_mem(addr: int, memaddr: int, nbytes: int, *, addrsize: int = 8) bytes¶
Đọc nbytes từ thiết bị ngoại vi được chỉ định bởi addr bắt đầu từ địa chỉ bộ nhớ được chỉ định bởi memaddr. Đối số addrsize chỉ định kích thước địa chỉ theo bit. Trả về đối tượng
bytesvới dữ liệu đã đọc.
- readfrom_mem_into(addr: int, memaddr: int, buf: bytearray, *, addrsize: int = 8) None¶
Đọc vào buf từ thiết bị ngoại vi được chỉ định bởi addr bắt đầu từ địa chỉ bộ nhớ được chỉ định bởi memaddr. Số byte đọc là độ dài của buf. Đối số addrsize chỉ định kích thước địa chỉ theo bit.
Phương thức trả về
None.
lớp SoftI2C -- bus I2C mô phỏng bằng phần mềm¶
Lớp SoftI2C triển khai I2C bằng cách bit-banging các chân GPIO tùy ý. Nó cung cấp cùng giao diện phương thức như I2C cộng thêm các thao tác bus nguyên thủy cấp thấp (start(), stop(), readinto(), write()) cho các lập trình viên cần tạo các giao dịch không chuẩn. Sử dụng khi các chân (pin) bạn cần không được kết nối với khối I2C phần cứng, khi bạn cần nhiều bus hơn phần cứng cung cấp, hoặc để giao tiếp với các thiết bị yêu cầu các trình tự đặc biệt (xung nhịp phụ, lặp lại START sau khi ghi, v.v.).
Các hàm khởi tạo¶
- class machine.SoftI2C(scl: Pin, sda: Pin, *, freq: int = 400000, timeout: int = 50000)¶
Xây dựng bus I2C phần mềm được điều khiển bởi
scl/sda.freqlà tốc độ xung nhịp SCL mục tiêu tính bằng Hz (tốc độ thực tế thường thấp hơn do chi phí vòng lặp bit-bang).timeoutlà thời gian tối đa tính bằng micro giây để chờ clock stretching (SCL bị kéo xuống thấp bởi thiết bị khác trên bus); khi hết thời gian sẽ xuất hiện ngoại lệOSError(ETIMEDOUT).Các phương thức chung¶
Các thao tác I2C nguyên thủy¶
Các phương thức sau đây triển khai các thao tác bus điều khiển I2C nguyên thủy và có thể kết hợp để tạo bất kỳ giao dịch I2C nào. Chúng chỉ dành cho SoftI2C -- lớp
I2Cphần cứng không cung cấp chúng.- readinto(buf: bytearray, nack: bool = True, /) None¶
Đọc các byte từ bus vào
buf. Đọclen(buf)byte; ACK được gửi sau mỗi byte trừ byte cuối cùng. Sau byte cuối cùng,nack=True(mặc định) gửi NACK để kết thúc truyền;nack=Falsegửi ACK để thiết bị vẫn được chọn choreadinto()tiếp theo.
Các thao tác bus tiêu chuẩn¶
Các phương thức sau đây triển khai các thao tác đọc và ghi điều khiển I2C tiêu chuẩn nhắm vào một thiết bị ngoại vi cụ thể.
- readfrom(addr: int, nbytes: int, stop: bool = True, /) bytes¶
Đọc
nbytestừ thiết bị tại địa chỉ 7-bitaddr. Nếustoplà true thì điều kiện STOP được tạo ra ở cuối quá trình truyền.
- readfrom_into(addr: int, buf: bytearray, stop: bool = True, /) None¶
Đọc
len(buf)byte từ thiết bị tạiaddrvàobuf. Nếustoplà true thì điều kiện STOP được tạo ra ở cuối quá trình truyền.
Các thao tác bộ nhớ¶
Một số thiết bị I2C hoạt động như thiết bị bộ nhớ (hoặc tập hợp các thanh ghi) có thể đọc và ghi. Trong trường hợp này có hai địa chỉ liên quan đến giao dịch I2C: địa chỉ ngoại vi và địa chỉ bộ nhớ. Các phương thức sau đây là các hàm trợ giúp tiện ích để giao tiếp với các thiết bị như vậy.
- readfrom_mem(addr: int, memaddr: int, nbytes: int, *, addrsize: int = 8) bytes¶
Đọc
nbytestừ thiết bị tạiaddrbắt đầu từ thanh ghimemaddr.addrsizelà chiều rộng địa chỉ thanh ghi theo bit (thường là8hoặc16).