class I2C -- 雙線序列協定

I2C 是一種用於裝置間通訊的雙線協定。在實體層上,它由兩條線組成:SCL(時脈)與 SDA(資料)。OpenMV Cam 在任一條線上提供板載上拉電阻——匯流排要能運作,SCLSDA 兩者都需要外部上拉電阻。

I2C 物件附加於特定的匯流排,可在建構時初始化,或稍後透過 init() 初始化。

範例:

from pyb import I2C

i2c = I2C(2)                              # create on bus 2 (uninitialised)
i2c = I2C(2, I2C.CONTROLLER)              # create and init as a controller
i2c.init(I2C.CONTROLLER, baudrate=20000)  # init as a controller
i2c.init(I2C.PERIPHERAL, addr=0x42)       # init as a peripheral with the given address
i2c.deinit()                              # turn off the peripheral

印出 I2C 物件會顯示其組態。

基本方法為 send()recv():

i2c.send("abc")      # send 3 bytes
i2c.send(0x42)       # send a single byte, given by the number
data = i2c.recv(3)   # receive 3 bytes

若要就地接收,請先建立一個 bytearray:

data = bytearray(3)  # create a buffer
i2c.recv(data)       # receive 3 bytes, writing them into data

你可以指定逾時(以 ms 為單位):

i2c.send(b"123", timeout=2000)   # timeout after 2 seconds

控制器必須指定接收方的位址:

i2c.init(I2C.CONTROLLER)
i2c.send("123", 0x42)        # send 3 bytes to peripheral with address 0x42
i2c.send(b"456", addr=0x42)  # keyword for address

控制器還具有下列這些方法:

# Check if peripheral 0x42 is ready.
i2c.is_ready(0x42)

# Scan the bus and return a list of responding addresses.
i2c.scan()

# Read 3 bytes from peripheral 0x42 starting at memaddr 2.
i2c.mem_read(3, 0x42, 2)

# Write 3 bytes to peripheral 0x42 at memaddr 2.
i2c.mem_write("abc", 0x42, 2, timeout=1000)

建構函式

class pyb.I2C(bus: int | str, *args, **kwargs)

在給定的 bus(一個整數周邊索引,例如 2 代表 I2C2)上建構一個 I2C 物件。若未提供其他參數,物件會被建立但不會被初始化(它會保留先前的匯流排設定,若有的話);若提供了額外引數,則匯流排會被初始化。可用的參數請參閱 init()

I2C(2) 在每一款公開 pyb.I2C 的 OpenMV Cam(M4 / M7 / H7 / H7 Plus / Pure Thermal)上都接到相同的排針接腳:

訊號

排針接腳

備註

SCL

P4

SDA

P5

I2C(4) 在 OpenMV Cam M7、H7、H7 Plus 與 Pure Thermal 上另外可用,其 SCL 在排針接腳 P7 上,SDA 在排針接腳 P8 上。

OpenMV Cam N6 不公開 pyb.I2C;請改用 machine.I2C

方法

deinit() None

關閉 I2C 匯流排。

init(mode: int, *, addr: int = 0x12, baudrate: int = 400000, gencall: bool = False, dma: bool = False) None

以給定的參數初始化 I2C 匯流排:

  • mode 必須是 I2C.CONTROLLERI2C.PERIPHERAL

  • addr 是 7 位元位址(只對周邊裝置有意義)。

  • baudrate 是 SCL 時脈速率(只對控制器有意義)。

  • gencall 為是否支援通用呼叫(general-call)模式。

  • dma 為是否允許在 I2C 傳輸中使用 DMA(請注意,DMA 傳輸的時序較精確,但目前無法正確處理匯流排錯誤)。

實際的時脈頻率可能低於要求的頻率。這取決於平台硬體。實際速率可透過印出 I2C 物件來得知。

is_ready(addr: int) bool

檢查 I2C 裝置是否回應給定的位址。僅在控制器模式下有效。

mem_read(data: int | bytearray, addr: int, memaddr: int, *, timeout: int = 5000, addr_size: int = 8) bytes

從 I2C 裝置的記憶體讀取:

  • data 可以是整數(要讀取的位元組數)或要讀入的緩衝區

  • addr 是 I2C 裝置位址

  • memaddr 是 I2C 裝置內的記憶體位置

  • timeout 是等待讀取的逾時時間,以毫秒為單位

  • addr_size 選擇 memaddr 的寬度:8 或 16 位元

傳回讀取的資料。這僅在控制器模式下有效。

mem_write(data: int | bytes | bytearray, addr: int, memaddr: int, *, timeout: int = 5000, addr_size: int = 8) None

寫入 I2C 裝置的記憶體:

  • data 可以是整數或要寫出的緩衝區。

  • addr 是 I2C 裝置位址。

  • memaddr 是 I2C 裝置內的記憶體位置。

  • timeout 是等待寫入的逾時時間,以毫秒為單位。

  • addr_size 選擇 memaddr 的寬度:8 或 16 位元。

僅在控制器模式下有效。

recv(recv: int | bytearray, addr: int = 0x00, *, timeout: int = 5000) bytes

在匯流排上接收資料:

  • recv 可以是整數,即要接收的位元組數,或是一個可變的緩衝區,將以接收到的位元組填入

  • addr 是要接收的來源位址(僅在控制器模式下需要)

  • timeout 是等待接收的逾時時間,以毫秒為單位

傳回值:若 recv 是整數,則為一個內含所接收位元組的新緩衝區,否則為傳入 recv 的同一個緩衝區。

send(send: int | bytes | bytearray, addr: int = 0x00, *, timeout: int = 5000) None

在匯流排上傳送資料:

  • send 是要傳送的資料(要傳送的整數,或緩衝區物件)。

  • addr 是要傳送的目標位址(僅在控制器模式下需要)。

  • timeout 是等待傳送的逾時時間,以毫秒為單位。

scan() List[int]

掃描從 0x01 到 0x7f 的所有 I2C 位址,並傳回回應的位址清單。僅在控制器模式下有效。

常數

CONTROLLER: int

將匯流排初始化為主控端(控制器)——它會驅動 SCL 並發起交易。

PERIPHERAL: int

將匯流排初始化為從屬端(周邊裝置),它會在 init() 中所設定的 addr 上監聽,並回應同一匯流排上控制器發起的交易。