I2C-協定用法原理簡介-晶片溝通的橋樑

以下圖案皆摘自NXP此篇文章
http://www.nxp.com/documents/user_manual/UM10204.pdf
i2c
I2C(Inter-Integrated Circuit),唸做I-square-C,它是NXP(前身為飛利浦)開發的通訊協定,主要用來做為IC之間的通訊。它的速度一般是100Kbit/s,有些是400Kbit/s,現在更有到1M bit/s與3.4Mbit/s,因此無法像Ethernet那麼快,所以不適合傳送大量資料。但是它又比RS232快速,所以它非常適合拿來設定IC初始值,或是IC之間的控制訊號傳輸。由於I2C只用兩條線通訊SDA(data)/SCL(clock),因此空間超級省。厲害的通訊協定總是要有個像樣的icon,上方是NXP為它設計的Icon。

I2C 是Master/Slave架構
I2C 是Master/Slave架構

甚麼東西最常用到I2C呢? 一般就是小型IC,例如Serial EEPROM/ Tuner/ Demodulator/ MCU/ ADC 等等。I2C 是master/slave架構,一個系統內通常只能有一個master,其他裝置只能當slave。我說”通常”是因為spec裡面有寫它可以multimaster,但是實務上我遇到的都只有一個master配多個slave,所以我就只討論single master。

I2C 如何傳資料

I2C是序列式的傳輸,只用兩條線,一個叫做SDA專門用來送資料,另一個叫做SCL是用來傳clock。資料格式如下圖,依序是由start condition所開始,然後開始傳資料,最後stop condition結束。所謂start condition就是這兩條線的某種狀態的組合可以拿來認定傳輸的開始。

I2C 的時序圖,依照Start-Data-Stop傳送資料
I2C 的時序圖,依照Start-Data-Stop傳送資料

上圖最左邊是Start condition: SCL=high + SDA falling
上圖最右邊是Stop condition: SCL=high + SDA raising

至於中間的資料,它是以8+1bit為一組來傳送的,意思是說8bit data外加1bit的Acknowledge,ACK是slave用來回應master用的,表示已經收到資料了。clock的positive pulse必須完整包含在bit data之內。以上就是I2C在physical layer的資料傳送說明,那一般IC如何應用它呢? 我們來看下面的例子實際體會一下

I2C protocol應用實例說明

這是一顆EEPROM的I2C使用說明,敘述這顆IC如何利用I2C來與外界溝通

I2C 通訊格式應用實例
I2C 通訊格式應用實例,摘自microchip的EEPROM datasheet http://ww1.microchip.com/downloads/en/DeviceDoc/20001203U.pdf

上圖的意思就是,你若要寫一個byte,就必須要傳送4個byte的指令,我說明如下。

第一個byte是I2C位址

這顆EEPROM的位址是1010[A2][A1][A0]0,可以讓IC知道之後面3個byte資料是要傳給自己的。相信你也看到了A2,A1,A0這甚麼東西呢?這個是讓user自行定義I2C address的功能(圖中稱呼為Control byte),若有需要同時使用兩顆EEPROM,user可以自行用IC的兩根腳位來定義I2C address。所以你可以在IC的A2~A0腳位上接Vcc或接GND用來表示1 or 0,這樣就能達成自訂address的目的

EEPROM的pinout
EEPROM的pinout

第2,3個byte是記憶體位址

這是一顆256Kbit (32K byte)的記憶體,這兩個byte是用來告訴EEPROM你想把資料寫在哪個位址。

第4個byte是資料

我想這個data byte就不多說了,就data而已。

I2C通訊成功要有ACK

目前的說明對於一般人應該是沒甚麼大問題。然而魔鬼總是藏在細節裡,若各位有寫Firmware,應該多少會遇到這種狀況,data、clock都送了,IC就是不動作,該怎麼辦? 在這個階段,我看過的作法有加delay、改變程式的呼叫順序等等,總之就是無法解問題,其實上述的處理方式大都是下意識地迴避I2C訊號的檢查。

我建議這時你應該要拿起示波器,看看第9個bit ACK是否為low,ACK low表示資料有收到。ACK是判斷Master/Slave之間通訊是否正常的重要依據。你看時序圖每個byte傳送完都是low (若正常動作的話),。

那麼是否每個byte的通訊都會有ACK呢? 那可不一定,因為每顆IC對於I2C的使用有自己的format,我們來看下圖,這是random read的指令序列

通常I2C read指令中間會多一個start condition
通常I2C read指令中間會多一個start condition

最開始的3個byte很好裡解 address + addrH + addrL,接下來各位要注意,它多了一個start condition,有些datasheet會把這裡的start寫成re-start,其實都是同一件事。Start之後緊接著又是I2C address,這裡又要注意另外一件事,就是I2C的address有分為兩類,write address與read address,他們的差別在於最後一個bit是0 or 1,0表示write ,1表示read。

例如
Addr=0xA0表示後面的byte是master要寫入slave的資料。
Addr=0xA1表示後面的byte是master要從slave讀出的資料。

目前走到第二個start這裡,都是master傳送SDA/SCL,一旦read address傳送結束,master就不再送SDA了,master只送SCL。SDA留給slave把資料傳回來,而最後一個bit就是NACK(high),NACK的意義就是回傳的最後一個byte。通常寫Firmware的人會知道自己期望讀多少byte,然而實際回傳的byte數量,只能由NACK來做判斷。

I2C很方便,只是要留意的小地方很多,NACK , 2nd Start (re-start)這種東西要多留意,只要protocol正確,chip一定會動作。寫Firmware的人通常手上的板子是工程樣品,所以你的元件功能不見得是正常的,所以遇到問題一定要拿起示波器Debug,才能真正寫出符合該Hardware的程式。

3 Comments

  1. 受益良多,最近在研讀UART I2C RS232溝通機制的資料
    UART 也是只有兩條線 uplink/downlink 但似乎沒有CLK去同步傳輸
    請問UART 跟I2C還有甚麼很重要的差別嗎?

    • UART用在人機介面, 所以還可以串成RS232,
      速率慢 最多115200 對UI來說夠用

      I2C用在IC之間, 速度到400K
      讀寫小量register資料很OK

      這兩個本來就是不同的protocol, 你應該從應用面來比較才有意義

1 Trackback / Pingback

  1. 示波器Trigger篇-了解各種觸發設定 – 實作派電子實驗室

Leave a Reply

Your email address will not be published.


*