版權聲明:本文為部落客原創文章,未經部落客允許不得轉載。
1、基本概念
主機 初始化發送,産生時鐘信号和終止發送的器件
從機 被主機尋址的器件
發送器 發送資料到總線的器件
接收器 從總線接收資料的器件
多主機 同時有多于一個主機嘗試控制總線 但不破壞封包
仲裁 是一個在有多個主機同時嘗試控制總線,但隻允許其中一個控制總線并使封包不被破壞的過程
同步 兩個或多個器件同步時鐘信号的過程
2、硬體結構
每一個I2C總線器件内部的SDA、SCL引腳電路結構都是一樣的,引腳的輸出驅動與輸入緩沖連在一起。其中輸出為漏極開路的場效應管、輸入緩沖為一隻高輸入阻抗的同相器。這種電路具有兩個特點:
(1)由于 SDA、SCL 為漏極開路結構,借助于外部的上拉電阻實作了信号的“線與”邏輯;
(2)引腳在輸出信号的同時還将引腳上的電平進行檢測,檢測是否與剛才輸出一緻。為 “時鐘同步”和“總線仲裁”提供硬體基礎。
3、時鐘同步
如果從機希望主機降低傳送速度可以通過将SCL主動拉低延長其低電平時間的方法來通知主機,當主機在準備下一次傳送發現SCL的電平被拉低時就進行等待,直至從機完成操作并釋放SCL線的控制控制權。這樣以來,主機實際上受到從機的時鐘同步控制。可見SCL線上的低電平是由時鐘低電平最長的器件決定;高電平的時間由高電平時間最短的器件決定。這就是時鐘同步,它解決了I2C總線的速度同步問題。
4、主機發送資料流程
(1)主機在檢測到總線為“空閑狀态”(即 SDA、SCL 線均為高電平)時,發送一個啟動信号“S”,開始一次通信的開始
(2)主機接着發送一個指令位元組。該位元組由 7 位的外圍器件位址和 1 位讀寫控制位 R/W組成(此時 R/W=0)
(3)相對應的從機收到指令位元組後向主機回饋應答信号 ACK(ACK=0)
(4)主機收到從機的應答信号後開始發送第一個位元組的資料
(5)從機收到資料後傳回一個應答信号 ACK
(6)主機收到應答信号後再發送下一個資料位元組
(7)當主機發送最後一個資料位元組并收到從機的 ACK 後,通過向從機發送一個停止信号P結束本次通信并釋放總線。從機收到P信号後也退出與主機之間的通信
注意:①主機通過發送位址碼與對應的從機建立了通信關系,而挂接在總線上的其它從機雖然同時也收到了位址碼,但因為與其自身的位址不相符合,是以提前退出與主機的通信;②主機的一次發送通信,其發送的資料數量不受限制。主機是通過
P 信号通知發送的結束,從機收到 P 信号後退出本次通信;③主機的每一次發送後都是通過從機的 ACK
信号了解從機的接收狀況,如果應答錯誤則重發。
5、主機接收資料流程
(1)主機發送啟動信号後,接着發送指令位元組(其中 R/W=1)
(2)對應的從機收到位址位元組後,傳回一個應答信号并向主機發送資料
(3)主機收到資料後向從機回報一個應答信号
(4)從機收到應答信号後再向主機發送下一個資料
(5)當主機完成接收資料後,向從機發送一個“非應答信号(ACK=1)”,從機收到ASK=1 的非應答信号後便停止發送
(6)主機發送非應答信号後,再發送一個停止信号,釋放總線結束通信
注意:主機所接收資料的數量是由主機自身決定,當發送“非應答信号/A”時從機便結束傳送并釋放總線(非應答信号的兩個作用:前一個資料接收成功,停止從機的再次發送)。
6、總線死鎖原因分析
I2C總線寫操作過程中,主機在産生啟動信号後控制SCL産生8個時鐘脈沖,然後拉低SCL信号為低電平,在這個時候,從機輸出應答信号,将SDA信号拉為低電平。如果這個時候主機異常複位,SCL就會被釋放為高電平。此時,如果從機沒有複位,就會繼續I2C的應答,将SDA一直拉為低電平,直到SCL變為低電平,才會結束應答信号。而對于主機來說,複位後檢測SCL和SDA信号,如果發現SDA信号為低電平,則會認為I2C總線被占用,會一直等待SCL和SDA信号變為高電平。這樣,主機等待從機釋放SDA信号,而同時從機又在等待主機将SCL信号拉低以釋放應答信号,兩者互相等待,I2C總線進人一種死鎖狀态。同樣,當I2C進行讀操作時,從機應答後輸出資料,如果在這個時刻主機異常複位而此時從機輸出的資料位正好為0,也會導緻I2C總線進入死鎖狀态。
解決方案通常有如下幾種:
(1)将從機的電源設計為可控,當發生總線死鎖的時将從機複位
(2)可以在從機的程式中加入監測功能,如果總線長時間被拉低則釋放對總線的控制
(3)在主機中增加I2C總線恢複程式。每次主機複位後,如果檢測到SDA被拉低,則控制SCL産生<=9個時鐘脈沖(針對8位資料的情況),每發送一個時鐘脈沖就檢測SDA是否被釋放,如果SDA已經被釋放就再模拟産生一個停止信号,這樣從機就可以完成被挂起的讀寫操作,從死鎖狀态中恢複過來。這種方法有一定的局限性,因為大部分主機的I2C子產品由内置的硬體電路來實作,軟體并不能夠直接控制SCL信号模拟産生需要時鐘脈沖
7、處理器的I2C子產品會在如下所述的情況産生中斷信号
RX_UNDER 當處理器通過IC_DATA_CMD寄存器讀取接收緩沖器為空時置位
RX_OVER 當接收緩沖器被填滿,而且還有資料從外設發送過來時被置位;緩沖器被填滿後接收的資料将會丢失
RX_FULL 當接收緩沖器達到或者超過IC_RX_TL寄存器中規定的門檻值時被置位;當資料低于門檻值時标志位将被自動清除
TX_OVER 當發送緩沖器被填滿,而且處理器試圖發送另外的指令寫IC_DATA_CMD寄存器時被置位
TX_EMPTY 當發送緩沖器等于或者低于IC_TX_TL寄存器中規定的門檻值時被置位;當資料高于門檻值時标志位将被自動清除
RD_REQ 當i2c子產品作為從機時并且另外的主機試圖從本子產品讀取資料時被置位
TX_ABRT 當i2c子產品無法完成處理器下達的指令時被置位,有如下幾種原因:
* 發送位址位元組後沒有從機應答
* 位址識别成功後主機發送的資料從機沒有應答
* 當i2c子產品隻能作為從機時試圖發送主機指令
* 當子產品的RESTART功能被關閉,而處理試圖完成的功能必須要RESTART功能開啟才能完成
* 高速子產品主機代碼被應答
* START BYTE被應答
* 子產品仲裁失敗
無論标志位什麼時候被置位,發送緩沖器和接收緩沖器的内容都會被重新整理
RX_DONE 當i2c子產品作為從機發送資料時,如果主機沒有應答則置位;這種情況發生在i2c子產品發送最後一個位元組資料時,表明傳輸結束
ACTIVITY 表明i2c子產品正在活動,這個标志位将會一直保持直到用以下4種方式清除:
* 關閉i2c
* 讀取IC_CLR_ACTIVITY寄存器
* 讀取IC_CLR_INTR寄存器
* 系統重新開機
即使i2c子產品是空閑的,這個标志仍然需要被置位直到被清除,因為這表明i2c總線上有資料正在傳輸
STOP_DET 表明i2c總線上産生了STOP信号,無論子產品作為主機還是從機
START_DET 表明i2c總線上産生了START信号,無論子產品作為主機還是從機
【新浪微網誌】 張昺華--sky
【twitter】 @sky2030_
【facebook】 張昺華 zhangbinghua
本文版權歸作者和部落格園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接配接,否則保留追究法律責任的權利.