簡單優雅的匯流排協議——I2C
這是IC君的第16篇原創文章 (同步於公眾號 icstudy)
IC君前一篇文章提到的NXP的datasheet如何閱讀datasheet,描述了一個I2C協議傳輸的EEPROM。這篇文章我們就來聊一聊I2C匯流排協議。I2C(Inter-Integrated Circuit)匯流排是80年代PHILIPS公司開發的
兩線式
序列匯流排,如今已經成為晶片間
低速
序列通訊的事實標準,被廣泛使用在消費、控制類電子裝置場合。這裡的兩個關鍵詞
兩線
和
低速
:
兩線
意味著結構簡單,
低速
意味著好實現,做電路的都知道速度越慢電路實現起來就越容易,而且協議方式也很優雅。一個簡單、優雅、好實現、應用又廣泛的電路協議是不是有必要了解一下呢?
IC君當年簡歷裡面就寫了曾經研究過I2C匯流排,有些面試官還挺感興趣哦!
下圖是一個典型的嵌入式系統的I2C匯流排應用,系統包含了很多slave從器件,最左邊的微控制器是I2C的主器件,它控制了I/O擴贊器、LED閃光燈、ADCs/DAC、EEPROM、LCD驅動器、溫度放大器等。
所有這些器件都是透過2根線:時鐘SCL和資料SDA來控制。
I2C匯流排使用的是開漏結構,這樣它可以進行資料的雙向傳輸。下圖是一個SDA/SCL線的基本結構,如果Slave或者Master內部的邏輯要用SDA/SCL線的時候,會透過內部的NMOS把SDA/SCL線下拉為地或者0;如果沒有Slave或者Master使用SDA/SCL線的時候,上拉電阻Rpu會把SDA/SCL上拉為VDD或high。
總線上有這麼多器件,顯然需要靠地址來確定訪問哪一個器件。主器件與從器件的通訊需要傳送一個開始條件和一個結束條件。如下圖所示:
開始條件:
SCL high, SDA high-to-low 轉換
結束條件:
SCL high, SDA low-to-high 轉換
開始條件傳送之後,就可以傳輸資料了,如下圖所示I2C協議要求:
傳輸時鐘SCL high期間,資料線SDA必須保持穩定;
SDA變化相對於SCL的go high 沿有setup時間的要求;
SDA 變化相對於SCL go low 沿有hold 時間的要求;
在SCL low 期間,資料SDA才能改變。
而且這裡的setup/hold 時間量級是
微秒級的或者幾百納秒,
慢速有點體會了吧,一般I2C的頻率最快也就1Mhz左右。所以I2C總線上的從器件一般不適合高速數字邏輯電路。
下圖中傳輸的資料是0xAAh, 一般地址定義為7位(支援127種不同的IIC裝置,如果需要更多器件可以擴充套件地址),第8位表示讀還是寫,最後還會跟一個ACK或NACK,如果從器件A的地址為1010101,
A說我現在有空,趕緊過來撩我吧,它會把SDA下拉到low;
A說我現在沒空,不想理你,它就不會下拉SDA,主器件那邊有上拉電路把SDA拉到high。
下圖就是一個完整的定址、輸入資料寫到一個從器件的過程。其中灰色表示主器件控制SDA線,白色表示從器件控制SDA。A6-A0是用來定址從器件的,相當於地圖上一棟樓的名字;B7-B0是從器件自己內部的地址,相當於這棟樓內部的某個房間;D7-D0是往這個房間裡面送東西。這裡是為了形象理解,樓可以直接替換為EEPROM。
注意器件地址後面跟了一個R/W bit,這裡置為“0”表示寫。每一個byte資料後面都有一個ACK/NACK,來確認從器件現在是不是有空;上面的圖只顯示輸入了一個byte,主器件可以寫入更多的byte資料,只要不傳送結束條件。
下面是一個主器件到從器件中讀取資料的過程,與上面的寫過程非常類似。其中灰色表示主器件控制SDA線,白色表示從器件控制SDA。
具體執行過程:
step1 :START+器件地址(R/W bit 置為0,執行寫)+暫存器地址;
step2 : 重複START+器件地址(R/W bit置為1,執行讀)+從器件輸出data(1個或多個byte)+STOP。
step1 是為了設定暫存器地址,相當於告訴你門牌號;step2 是去讀這個暫存器地址指向的內容,也就是去這個門牌號指示的地方。
step1+step2的過程也可以稱為隨機讀;
如果沒有step1,直接執行step2就是
順序讀
的操作,如下圖所示,因為每次讀寫1個byte內部的暫存器地址都會加1,所以順序讀就是以上次讀寫之後的暫存器地址為起點,繼續讀下去。
然有的I2C還支援一些奇怪的指令,這個要看具體的產品。
基本上I2C通用的讀和寫的操作就講完了,來個總結:
I2C最大的優點是結構簡單,2根線完美連線所有器件。缺點是速度太慢,最快也就幾 Mbps左右,而且每傳一個BYTE就要ACK/NACK,感覺也挺煩的。
有沒有既簡單又不那麼慢的序列匯流排協議呢?確實有,SPI (Serial Peripheral Interface)協議,後面IC君也會重點介紹它
基礎概念講完了,後續文章會找一些電路和程式碼來繼續分析I2C協議,敬請期待~
如果覺得文章有用,麻煩轉發和分享到朋友圈,謝謝!