3.23. I2C 基礎¶
I2C(Inter-Integrated Circuit,唸作「I-squared-C」或「I-two-C」)是一種雙線串列匯流排,專為同一塊板上晶片間的短距離連結而設計。它在優先順序上介於 SPI 與 UART 之間:比 SPI 慢,但更節省接腳,而且具有定址能力(同樣兩條線上可掛多個裝置),不像 SPI 每個裝置都需要一條專屬的 CS 線。
I2C 是低速率感測器的首選匯流排——加速度計、溫度感測器、濕度感測器、磁力計、即時時鐘、EEPROM——這類應用中,節省接腳與降低匯流排複雜度比原始吞吐量更重要。
3.23.1. 兩條線、皆為開汲極¶
一條 I2C 匯流排只有兩個訊號:
SCL(串列時脈)。(多數時候)由控制器驅動。
SDA(串列資料)。由當下正在說話的裝置驅動——位址與外送資料期間是控制器,讀取與 ACK 位元期間是周邊裝置。
兩條線皆為開汲極:匯流排上的每個裝置都能把線拉低到接地,但永遠不會主動把線驅動為高。匯流排上的兩個上拉電阻(通常為接往供電軌的 2.2 kΩ 到 10 kΩ)會在沒有人拉低時把線拉高。線及邏輯(wired-OR)行為由此而生——任何把線拉低的裝置即勝出,而高電位狀態僅代表「沒有人在說話」。
MCU 在其 SCL 與 SDA 接腳上的內部上拉通常不足以單獨充當匯流排上拉;正常情況下需要在匯流排上加裝外部電阻。許多感測器轉接板已內含這些電阻;在加裝更多之前請先查閱資料手冊。
3.23.2. 交易(transaction)¶
每一次 I2C 交易都遵循相同的形態:
一次 I2C 交易:START、7 位元位址 + R/W、ACK、暫存器、ACK、資料、NACK、STOP。¶
整個交換逐位元展開:
START。 控制器在 SCL 仍為高時把 SDA 拉低。這個不尋常的邊緣告訴匯流排上的每個裝置:一次交易即將開始。
位址 + R/W。 控制器送出一個 7 位元周邊位址,後接一個讀/寫位元(
0表示寫入、1表示讀取)。ACK / NACK。 每個位元組之後,接收方會在一個時脈期間驅動 SDA 以表示 ACK(低)或 NACK(高)。對位址位元組而言,周邊裝置若辨識出自己的位址便會回應 ACK;若沒有裝置回應 ACK,控制器看到 NACK,便知道該位址不在匯流排上。
資料位元組。 每一個之後都跟著來自接收方的一個 ACK。寫入時,周邊裝置對每個位元組回應 ACK;讀取時,控制器對每個它還想要的位元組回應 ACK,並對最後一個位元組回應 NACK,以告知周邊裝置停止。
STOP。 控制器在 SCL 為高時釋放 SDA 使其為高,結束這次交易。
重複起始(repeated start)是指在中途不發出 STOP 的情況下發出第二個 START——控制器在不放棄匯流排的前提下,於同一個周邊裝置上切換方向(先寫位址、再讀位址)。
3.23.3. 定址¶
7 位元位址空間涵蓋 0x08 到 0x77;兩端的數值保留作特殊用途。每個裝置的位址由晶片設計者設定;許多元件允許在板級層面變更低位元中的幾個位元(藉由把某接腳接高或接低),如此一來兩顆相同的感測器便能掛在同一條匯流排上。
若兩個裝置共用同一位址,就無法在不互相干擾的情況下與其中之一通訊,因此配對元件前請先查閱資料手冊。i2c.scan()(於 以程式碼操作 I2C 中說明)會遍歷位址空間並回報哪些位址有回應,這是查明匯流排上有什麼的標準做法。
3.23.4. 優點與缺點¶
這條匯流排的優缺點界定了它的定位:
兩支接腳掛許多裝置。 單一組 SCL/SDA 即可承載十幾個感測器。SPI 則需要每個裝置額外一支 CS 接腳。
標準速度。
100 kHz(「標準模式」)與400 kHz(「快速模式」)幾乎涵蓋每一種感測器。1 MHz可達,但開始對匯流排電容與上拉電阻的取值提出更高要求。相對於 SPI 較慢。 任何傳輸超過每秒數百千位元的應用都會改用 SPI。
位址衝突。 同一條匯流排上有兩個位址相同的裝置,是這個協定無法迴避的硬體錯誤。