class I2C -- 雙線串列協定¶
I2C 是一種用於裝置間通訊的雙線協定。在實體層上,它由 2 條線組成:SCL 與 SDA,分別為時脈線與資料線。
I2C 物件在建立時會附接至特定的匯流排。它們可以在建立時初始化,或稍後再行初始化。
列印 I2C 物件可取得其組態的相關資訊。
硬體與軟體 I2C 實作分別透過 I2C 與 SoftI2C 類別提供。硬體 I2C 利用系統底層的硬體支援來執行讀寫,通常有效率且快速,但可能限制可使用哪些接腳。軟體 I2C 以位元觸發(bit-banging)方式實作,可用於任何接腳,但效率不如硬體。這些類別提供相同的方法,主要差異在於建構方式。
備註
I2C 匯流排運作時需要在 SDA 與 SCL 上加裝上拉電路。通常這些是阻值範圍在 1 - 10 kOhm 的電阻,從各 SDA/SCL 連接至 Vcc。若沒有這些電阻,行為將無法預期,從阻塞、非預期的看門狗重置到單純的錯誤值都有可能。這類上拉電路通常已內建於 MCU 開發板或感測器擴充板上,但這並非通則。因此若遇到問題請務必檢查。亦可參閱 Adafruit 關於 I2C 接線這份出色的 學習指南。
使用範例:
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
建構式¶
- class machine.I2C(id: int, *, scl: Pin | None = None, sda: Pin | None = None, freq: int = 400000, timeout: int = 50000)¶
使用下列參數建構並回傳一個新的 I2C 物件:
id 用於識別特定的 I2C 周邊裝置。允許的值取決於特定的 port/開發板
scl 應為一個接腳物件,指定要用於 SCL 的接腳。
sda 應為一個接腳物件,指定要用於 SDA 的接腳。
freq 應為一個整數,用於設定 SCL 的最大頻率。
timeout 是允許 I2C 交易的最長時間,以微秒為單位。某些 port 不允許使用此參數。
請注意,某些 port/開發板會有 scl 與 sda 的預設值,可在此建構式中變更。其他則會有無法變更的 scl 與 sda 固定值。
一般方法¶
原始 I2C 操作¶
下列方法實作了原始的 I2C 控制器匯流排操作,可組合以構成任何 I2C 交易。當你需要更多對匯流排的控制時可使用它們,否則可使用標準方法(見下文)。
這些方法僅在
SoftI2C類別上可用。標準匯流排操作¶
下列方法實作了針對給定周邊裝置的標準 I2C 控制器讀寫操作。
- readfrom(addr: int, nbytes: int, stop: bool = True, /) bytes¶
從 addr 所指定的周邊裝置讀取 nbytes。若 stop 為真,則在傳輸結束時產生 STOP 條件。回傳一個包含所讀取資料的
bytes物件。
- readfrom_into(addr: int, buf: bytearray, stop: bool = True, /) None¶
從 addr 所指定的周邊裝置讀取資料至 buf。讀取的位元組數為 buf 的長度。若 stop 為真,則在傳輸結束時產生 STOP 條件。
此方法回傳
None。
- writeto(addr: int, buf: bytes, stop: bool = True, /) int¶
將 buf 中的位元組寫入 addr 所指定的周邊裝置。若在寫入 buf 中某個位元組後收到 NACK,則不再傳送剩餘的位元組。若 stop 為真,則即使收到 NACK,仍會在傳輸結束時產生 STOP 條件。此函式回傳所收到的 ACK 數量。
- writevto(addr: int, vector: tuple | list, stop: bool = True, /) int¶
將 vector 中所含的位元組寫入 addr 所指定的周邊裝置。vector 應為一個由具備緩衝協定的物件所組成的元組或清單。addr 只會送出一次,接著 vector 中每個物件的位元組會依序寫出。vector 中的物件長度可以為零位元組,此情況下它們不會對輸出有所貢獻。
若在寫入 vector 中某個物件的某個位元組後收到 NACK,則不再傳送剩餘的位元組以及任何剩餘的物件。若 stop 為真,則即使收到 NACK,仍會在傳輸結束時產生 STOP 條件。此函式回傳所收到的 ACK 數量。
記憶體操作¶
某些 I2C 裝置可作為記憶體裝置(或一組暫存器),可從中讀取與寫入。在此情況下,一次 I2C 交易會關聯兩個位址:周邊位址與記憶體位址。下列方法是用於與此類裝置通訊的便利函式。
- readfrom_mem(addr: int, memaddr: int, nbytes: int, *, addrsize: int = 8) bytes¶
從 addr 所指定的周邊裝置、自 memaddr 所指定的記憶體位址開始讀取 nbytes。引數 addrsize 以位元為單位指定位址大小。回傳一個包含所讀取資料的
bytes物件。
class SoftI2C -- 軟體模擬的 I2C 匯流排¶
SoftI2C 類別透過對任意 GPIO 接腳進行位元觸發(bit-banging)來實作 I2C。它公開與 I2C 相同的方法介面,並額外提供低階的原始匯流排操作(start()、stop()、readinto()、write()),供需要組裝非標準交易的呼叫端使用。當你需要的接腳未接至硬體 I2C 區塊、需要的匯流排數量多於硬體所提供、或需要與要求特殊序列(額外的時脈、寫入後重複的 START 等)的裝置通訊時,可使用它。
建構式¶
- class machine.SoftI2C(scl: Pin, sda: Pin, *, freq: int = 400000, timeout: int = 50000)¶
建構一個由
scl/sda驅動的軟體 I2C 匯流排。freq是目標 SCL 時脈速率,以 Hz 為單位(由於位元觸發迴圈的額外開銷,實際速率通常較低)。timeout是等待時脈延展(clock stretching,即匯流排上其他裝置將 SCL 持續拉低)的最長時間,以微秒為單位;逾時即會引發OSError(ETIMEDOUT)。一般方法¶
原始 I2C 操作¶
下列方法實作了原始的 I2C 控制器匯流排操作,可組合以構成任何 I2C 交易。它們僅限 SoftI2C 使用——硬體
I2C類別並不公開它們。- readinto(buf: bytearray, nack: bool = True, /) None¶
從匯流排讀取位元組至
buf。會讀取len(buf)個位元組;除最後一個外,每個位元組之後都會送出 ACK。在最後一個位元組之後,nack=True(預設值)會送出 NACK 以結束傳輸;nack=False則送出 ACK,使裝置維持選定狀態以供後續的readinto()。
標準匯流排操作¶
下列方法實作了針對給定周邊裝置的標準 I2C 控制器讀寫操作。
- readfrom(addr: int, nbytes: int, stop: bool = True, /) bytes¶
從 7 位元位址
addr的裝置讀取nbytes。若stop為真,則在傳輸結束時產生 STOP 條件。
- readfrom_into(addr: int, buf: bytearray, stop: bool = True, /) None¶
從
addr的裝置讀取len(buf)個位元組至buf。若stop為真,則在傳輸結束時產生 STOP 條件。
記憶體操作¶
某些 I2C 裝置可作為記憶體裝置(或一組暫存器),可從中讀取與寫入。在此情況下,一次 I2C 交易會關聯兩個位址:周邊位址與記憶體位址。下列方法是用於與此類裝置通訊的便利輔助函式。
- readfrom_mem(addr: int, memaddr: int, nbytes: int, *, addrsize: int = 8) bytes¶
從
addr的裝置、自暫存器memaddr開始讀取nbytes。addrsize是暫存器位址的寬度,以位元為單位(通常為8或16)。