以下圖案皆摘自NXP此篇文章
http://www.nxp.com/documents/user_manual/UM10204.pdf
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呢? 一般就是小型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就是這兩條線的某種狀態的組合可以拿來認定傳輸的開始。
上圖最左邊是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來與外界溝通
上圖的意思就是,你若要寫一個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的目的
第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的指令序列
最開始的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的程式。
受益良多,最近在研讀UART I2C RS232溝通機制的資料
UART 也是只有兩條線 uplink/downlink 但似乎沒有CLK去同步傳輸
請問UART 跟I2C還有甚麼很重要的差別嗎?
UART用在人機介面, 所以還可以串成RS232,
速率慢 最多115200 對UI來說夠用
I2C用在IC之間, 速度到400K
讀寫小量register資料很OK
這兩個本來就是不同的protocol, 你應該從應用面來比較才有意義
好的,我會在蒐集一些相關應用層面的資料來研讀
謝謝您