I2C (Inter-Integrated Circuit)
I2C 是 I2C Bus簡稱,也就是 Inter-Integrated Circuit Bus,也就是在 IC 之間的匯流排,使得 IC 跟 IC 可以通訊。
I2C 是一種串列通訊匯流排,使用多主從架構,由飛利浦公司在1980年代為了讓主機板、嵌入式系統或手機用以連接低速週邊裝置而發展。
I2C 使用兩條雙向漏極開路(Open Drain)線,如下:
1, SDA (Serial DAta line): 傳輸資料。
2, SCL (Serial CLock line): 啟動或停止傳輸以及傳送時鐘序列。
下圖為 I2C 線路範例,由兩個 master/slave 裝置 及兩個 slave 裝置組成,並搭配使用上拉電阻:
可以看到 SDA 及 SCL 都是雙向的。
I2C 的線路圖範例為:
在線路圖中,可以看到 SCL 是單向的,表示這個 I2C slave 裝置無法控制 SCL,也就是沒有支援 時脈擴展 的功能。
I2C 的操作原理
I2C bus上的訊號邏輯有以下規則:
1、I2C bus 為 idle high,也就是當 bus 上沒有任何活動時,SCL 和 SDA 都維持在 high。
2、SCL 為 high 時,表示 SDA 上的資料為有效(Data Validity),此時 SDA 的狀態不能改變,以確保接收方可以取樣到正確的 SDA 狀態。
3、SCL 為 low 時,SDA 的狀態可以改變。
4、當 SCL 為 high 時,如果 SDA 變動,有兩種特殊狀況:
4-1、SCL high、SDA 下降代表 START 時序狀態。
4-2、SCL high、SDA 上升代表 STOP 時序狀態。
每一個 8-bit(I2C是以1-byte為單位傳送data) 的資料傳輸結束後,會跟著一個 acknowledge bit(第9個bit)。這個 acknowledge bit 固定由接收方產生,有兩種用法:
當 master 是傳送方(Transmitter)、slave 是接收方(Receiver),也就是說這個傳輸是 master 寫入資料到 slave 時,這個 acknowledge bit 是用來讓 slave 告訴 master「收到!了解!正確!」
當 master 是接收方、slave 是傳送方,也就是說這個傳輸是 master 從 slave 讀取資料時,這個 acknowledge bit 是用來讓 master 告訴 slave「我還要接著讀,請繼續準備下一筆資料」或者是「夠了,我讀完了」。
傳送方會在 ACK 的 SCL 時脈釋放 SDA 線(SDA 為 high),如果接收方正常收到 data 的話,會在第 9 個 bit 將 SDA 拉 low,也就是回應 ACK。
如果接收方有任何狀況,或是 bus 上面根本就沒有那個 address 的 slave 裝置,到了第 9 個 SCL 週期時,當傳送方釋放 SDA 後,就沒有人去驅動 SDA,這時 SDA 就會因為上拉電阻(Rp)的關係維持在 high,如此一來,傳送方就知道出問題了,不會繼續接下來的傳輸,而要進行錯誤處理,這種情況稱之為「non-acknowledge」,或簡稱為「NACK」。
I2C的傳輸流程
Slave Address
I2C 是一個多裝置的 bus,因此每當 master 發起傳輸時,它得先點名,就像老師叫特定座號的同學回答問題一樣,而這個座號就是 Slave的 address。在最早的 I2C 規格中,I2C address 是 7-bit,同一個 bus 上不可以有兩個 address 一樣的 slave 裝置,因此 I2C bus 上最多可以有 128 個 slave 裝置,實務上有一些 address 是保留的不能使用,因此可用的數量會比 128 略少一點;至於 master,它沒有、也不需要 address,因為沒有人會點名老師起來回答問題。因此所有的 I2C 傳輸週期,第一個 byte 都是用來點名的,它的內容就是被點到裝置的 address。
伴隨著 7 個 bit 的 slave address 而來的第 8 個 bit,則是一個表示讀或寫的 bit,0 是寫入、1 是讀取;其中點名的 byte 永遠是寫入,因此在 slave address 後的 R/W bit 的值一定是 0。
寫入(Write)實例
I2C master 用 START 狀態發起傳輸後,接著是 slave address 以及 R/W bit,因爲這時是寫入 slave,因此 R/W bit 是 0,到了第 9 個 bit 時,傳輸方向會換過來,變成由 slave 向 master 傳送 acknowledge bit。
Master 收到 acknowledge 後,就會繼續切換 SCL,並在每一個 SCL 爲 high 的脈波週期中,依序送出資料的每一個 bit,總共 8 個 bit。
一樣到了第 9 個 bit 時,傳輸方向會換過來。Master 會在 SCL 變成 high 的第 9 個時脈週期中,放掉 SDA 不去驅動它(SDA 為 high),並監聽來自 slave 的狀態;如果 slave 在此時有把 SDA 驅動到 low,就代表 slave 有正確地收到了這個 byte 的資料傳輸。
最後,master 送出 STOP 狀態結束這一回合的傳輸,成功寫入 1 個 byte 的資料到 slave。
在寫入週期中,只要 master 沒有送出 STOP 狀態,而是持續不斷地切換 SCL 並將資料送出,就會變成一個連續寫入 data 的傳輸。
至於可以連續寫入多少筆資料,則要看 slave 這邊晶片的設計,當寫入太多筆資料,超過 slave 可以允許的範圍,它就會發 NACK 喊停,告訴 master 不要再寫了。
讀取(Read)實例
讀取和寫入流程類似,I2C master 用 START 狀態發起傳輸後,接著是填寫 slave address 以及 R/W bit,因爲這時是讀取 slave,所以 R/W bit 是 1,到了第 9 個 bit 時,傳輸方向會換過來,變成由 slave 向 master 傳送 acknowledge bit,之後就是 slave 向 master 傳送 data,當 master 讀完後,會發 ACK=0 告訴 slave 收到 data 了。
在連續讀取時,只要後面還會繼續讀,master 就要送出 ACK=1 的 acknowledge bit 告訴 slave 要準備提供接下來的資料,只有當後面不再讀取而接著 STOP 狀態時,ACK 才會是 0。
實例分析
下圖是一個典型的 I2C 波形:
在 SCL 為 high 時,SDA 從 high 變為 low,代表 START 時序狀態。
後續的 I2C 波型,直接讀取結果為:0b 1011 1010 0 1000 0001 0。
可以分為 4 個步驟來解讀:
1、其中前八個位元 0b 1011 1010,表示 8-bit slave address 為 0b 1011 1010 = 0xba。
進一步分析,前 7-bit 為此 I2C slave 裝置的 7-bit slave address,也就是 0b 1011 1010 >> 1 = 0b 0101 1101 = 0x5d。
而第 8 bit 為,R/W bit,其值為為 0,表示為寫入(write)。
2、後邊緊跟着的 0b 0 ,表示 slave 裝置回應 ACK,表示該 slave 裝置存在。
3、接著的八個位元 0b 1000 0001,為要寫入的數據 0b 1000 0001。
4、最後緊跟着的 0b 0 表示 slave 裝置回應 ACK,表示該 slave 裝置已有收到數據。
以目前的測量經驗來看,如果 I2C 的頻率為 100K,則 I2C 的單位間隔時間可以設為 20 us,如此可以輕鬆觀察到 I2C Data 及 I2C Clock 搭配下,所傳送的訊息內容。
以頻率為 100k 來看,每個 I2C 週期為 1 / 100000 s = 0.00001 s = 0.01 ms = 10 us。
在 linux 上,常使用的 i2c 指令有: i2cdetect, i2cget, i2cset, i2cdump, i2ctransfer,可以參考以下文章:
Linux 的 I2C 指令
Reference
Serial Buses Comparison: JTAG, SPI, and I2C
I2C bus 簡介 (Inter-Integrated Circuit Bus)
留言列表