1. 程式人生 > >詳解面試的必答題——I2C協議

詳解面試的必答題——I2C協議

目錄

第一部分:I2C協議的概述

第二部分:I2C協議的闡述

第三部分:AT24C04簡述

第四部分:基於verilog的程式設計(暫無)


對於大多從事FPGA行業的應屆生來說,在面試過程中很可能會被問到關於I2C協議的一些內容,尤其是碰到比較重視基本功的面試官,答好了,就是大大的加法,答不上了,也是大大的減分。為什麼呢?首先因為這個協議簡單,簡單的都不會必然容易引起人的遐想,其次,它很好的考查了應試者對時序對協議的理解,FPGA玩的就是時序,如果答不上了那就有理由懷疑FPGA學的程度了。故在此筆者將詳細的闡述IIC協議,並用AT24C04晶片進行實驗。


 第一部分:I2C協議的概述

I2C匯流排由Philips公司開發的一種簡單、雙向二線制同步序列匯流排,英文名稱為(Internal-Integrated Circuit Bus),也就是內建積體電路匯流排,它只需要兩根線即可實現系統內部各個連線於總線上的積體電路(IC)之間的資訊傳遞,可以說它是內部的公共通訊幹線。該協議起初是飛利浦為公司為了讓主機板、嵌入式系統用以連線低速周邊裝置而研發的,如今得到了廣泛應用。在平時,我們習慣把bus給省略了,稱之為I2C或者IIC。

I2C匯流排設計可為非常精巧,它用兩根線就可以實現總線上主從裝置之間的交流,並且支援分時複用多主多從,也就是說在同一時刻僅支援一主一從,如圖1所示。由於在晶片內部都有I2C相關的電路設計以相容I2C介面,且片上的濾波器可以濾去匯流排資料線上的毛刺波保證資料完整,故外部只需要加個上拉電阻即可。

                                                                                                     圖1 I2C匯流排

 

那麼為啥需要上拉電阻呢?因為飛利浦的I2C匯流排規範要求匯流排空閒時兩根線都必須為高,所以咱就得給人家加上。當然,其原因也是很好理解的。通過I2C進行資料通訊說白了就是檢測這兩根線上的狀態,即電平高低,試想,如果空閒是不定態或者說為低電平,那就無法實現這一需求了,畢竟誰也不能把低電平拉高。

這個上拉電阻也是有講究的,不是說隨便懟上一個就Ok了。總的來說電源電壓限制了上拉電阻的最小值,負載電容(匯流排電容)限制了上拉電阻的最大值。如果上拉電阻值過小,灌入埠的電流會變大,這樣會導致MOS管由飽和狀態變成放大狀態,這樣埠輸出的低電平值增大,I2C協議規定,埠輸出低電平的最高允許值為0.4V,故電阻不能太小。當然,上拉電阻太大致使負載電流太小也不成,但這個影響不及匯流排電容影響大,故可忽略。上拉電阻會和匯流排形容RC電路,這就會延長充電時間使得時鐘沿更緩,由此影響建立時間進而限制了時鐘速率。所以,I2C的上拉電阻可以一般選擇1.5K、2.2K或4.7K,如圖2所示。

                                                                                               圖2 ATLC04 硬體連線

 

由於I2C匯流排器件均為CMOS器件,CMOS器件的最大優點就是省電,耗電量極低,一般在微安級,所以I2C總線上基本不會出現電流驅動能力不足的問題,如果出現那設計者也忒摳了吧,這點電都不給。但I2C總線上的IC個數是有限制的,這個限制雖不受制於電流驅動能力,但受制於電容負載總量。

我們先說一下這個“電容負載總量”,也就是匯流排電容。匯流排電容即線路連線和管腳的總電容,或者可以理解為積體電路設計和走線中所不可避免產生的寄生電容。由於積體電路的特性使得協議需滿足一定的時序要求,也就是建立時間和保持時間,匯流排電容具有電壓滯後電流的特性,也就是會讓時鐘沿變緩,故為滿足時序要求,對匯流排電容有了限制。所以這個限制是跟頻率有關係的,在《I2C匯流排規範》我們可查閱到,I2C的序列8位雙向資料傳輸位速率在標準模式下可達100kbit/s,快速模式下可達400kbit/s,高速模式下可達3.4Mbit/s。標準模式最大匯流排電容為400pF,快速模式最大匯流排電容為20pF,如果你跑幾十bit/s,便可忽略這些限制。


第二部分:I2C協議的闡述

首先我們要想清楚協議是什麼?協議是人想出來的,是人為規定的器件之間交流的話,它們是源自於人、源自於生活的,可以說就是將生活中的現象在專業領域用另一種方式進行表述。我們是這些協議的設計者,所以我們將抽象的東西迴歸到生活,站在一個更高的位置去做巨集觀的理解,然後帶著這種理解去看某個協議,看某篇文件,我想會有不一樣的心態或許也會更有效率更有動力,或許心情會好一點,學習要開心嘛。I2C協議亦是如此。它的兩根線,一根作為時鐘線,在傳輸資料是按照一定的頻率不停跳變,一根雙向資料線,由主裝置進行控制,這兩根線不同的狀態就是人為規定的語法,不同狀態有序的轉換就形成了協議,也就是我們要傳輸的內容。

通訊亦如說話,有來有往,對於器件,就是有讀有寫。如圖3是主裝置寫(輸出)一個位元組的資料傳輸格式,如圖4所示,是主器件讀從器件的資料傳輸格式。其中,傳送到SDA線上的每個位元組(寫地址、寫資料、讀資料)必須為8位,每次傳輸可以傳送的位元組數量不受限制。“S”是start即開始起始的意思,“P”是stop,即停止結束的意思。

                                                                                                 圖3 I2C寫資料

                                                                                               圖4 I2C讀資料

根據圖3、4我們可以歸納出,I2C寫資料(主裝置輸出)是由“空閒+起始+寫+從應答+停止”來實現的,其中寫地址和寫資料都是寫。I2C讀資料是由“空閒+起始+寫+從應答+讀+主應答+不應答+停止”拼湊起來的。前文說過,I2C通過兩根線的不同狀態實現了資料交換,現在可以進一步說,是用I2C兩根線的不同形式表示了上述的起始、寫、讀等一些狀態,這些狀態又按照協議要求進行排列完成了資料內容的交換。所謂的不同形式也就是高電平、低電平、上升沿、下降沿這四種而已,下面我們來分析一下上圖的資料傳輸格式的這些狀態。

 

空閒即為無事所為之狀態,在該狀態資料線和時鐘先均處於高電平。

 

 主裝置發出起始訊號也就意味著通訊的開始,或讀或寫。起始訊號實在時鐘為高電平期間將資料線拉低,如圖所示。

 

寫資料就是主裝置向從裝置傳送內容,傳送內容的關鍵點是在時鐘的低電平期間可以改變資料,在高電平期間要保持資料內容不變,如圖所示,在時鐘電平資料線從“0”變成了“1”,那麼該時鐘週期傳送的資料則為“1”,為什麼高電平要保持呢?這是因為如果在時鐘線為高電平期間拉低資料線,則與起始訊號衝突,器件有傻傻的分不清,如果資料線由低電平變為高電平,則與停止訊號衝突,器件依舊分不清,那還穿什麼數呀。

 

 

 在寫資料期間,每傳送完一組(8bit)資料,必須由從裝置反饋一個應答訊號,以示從裝置接收到了資料,從應答是在期間主裝置釋放資料線,由於電路存在上拉電阻,因此資料線為高電平狀態,如果期間資料線被拉低,則表示從期間應答。

 

主應答是應用在主裝置連續讀期間,當主裝置讀完一組(8bit)資料,欲讀下一組資料時,主裝置需傳送主應答告知從裝置,這個要求不過分吧?主應答是在接收完資料的下一個時鐘將資料線拉低即可。

 

 

不應答是在主裝置讀一組資料之後不再讀資料了要告知從裝置的一種狀態訊號,也就是在讀完一組資料後的下一個時鐘不要將資料線拉低即可。

 

讀資料即為從裝置將資料內容在時鐘的伴隨下發送給主裝置,此時主裝置要釋放資料線,資料線交由從裝置控制,從裝置也是在時鐘低電平期間傳送資料,高電平期間維持資料不變。 

無論是讀還是寫,該訊號的出現都標誌著一次操作的完成,其方式時鐘的高電平期間將資料線有低拉高。隨後便進入了空閒狀態。

以上八種狀態的組合就會實現資料的交換如圖所示,接下來就以AT24C04為例闡述I2C協議的實際應用。 


第三部分:AT24C04簡述

AT24C04是Ateml公司的4Kb得電可擦除儲存晶片,採用I2C匯流排實現與主裝置進行資料交換。該晶片可以說是我們學習I2C協議的一個很好的實驗物件,而且還挺便宜。硬體結構也簡單,如圖所示。

其中,A0不是地址設定引腳,是用來定址的第9bit(隨後說),A1/A2器件地址設定引腳,是用來設定器件地址的,可以掛4個AT24c04。WP防寫,低電平可對整個AT24c04的512位元組進行讀寫操作,高電平則只讀不能寫。該晶片每頁的大小為8個位元組。寫操作有單位元組寫和連續寫,讀有讀當前地址資料、隨機讀和順序讀三種,下面就對此進行介紹。

1、單位元組寫操作:

單位元組寫操作如圖所示,就是用上述八種狀態進行組合,即

其中,寫從器件地址就是寫操作,高4bit是硬體ID,固定的,A2、A1根據硬體連線確定,由於4Kbit儲存空間的定址範圍是0到511,寫地址的8bit是不夠的,故用P0作為寫地址的最高位。

 

 2、連續寫

連續寫和單位元組寫是一樣的,但連續寫也不是你想寫多少就寫多少,AT24C04每頁大小為8byte,如果從頁起始來寫如(0000_0000或0000_1000),則可以寫8位元組,如圖從0000_0010。來寫,則最多隻能寫6位元組,在換頁之間還有有一定的延時。

 3、讀當前地址資料 

讀當前地址是操作最為簡單的一種操作方式,也是最不常用的一種方式,如圖所示,寫完裝置地址直接讀資料。

4、隨機讀單位元組

隨機讀顧名思義就是可以讀任意位置的一個位元組資料,其實可以說隨機讀是在讀當前地址資料上演化來的,我們將讀指標指向我們要讀的地址位置,再去讀當前地址資料就是隨意讀了。 

 5、順序讀 

順序讀說白了就是讀多位元組,如圖所示,當然讀也是有限制的,和連續寫一樣一樣的。


第四部分:基於verilog的程式設計

暫無