I2C總線(xiàn)協(xié)議分析
I2C總線(xiàn)是由Philips公司開(kāi)發(fā)的一種簡(jiǎn)單、雙向二線(xiàn)制同步串行總線(xiàn)。它只需要兩根線(xiàn)即可在連接于總線(xiàn)上的設備之間通信。I2C的兩根線(xiàn)SDA(串行數據線(xiàn))和SCL(串行時(shí)鐘線(xiàn))都是雙向I/O線(xiàn),接口電路為開(kāi)漏輸出,需通過(guò)上拉電阻接電源VCC,當總線(xiàn)空閑時(shí),兩根線(xiàn)都是高電平。
常見(jiàn)的硬件結構圖(一個(gè)適配器,兩根線(xiàn),若干設備而已)
使用I2C通信時(shí),必須指定主從設備,一般包含有I2C控制器的處理器被配置成主設備,掛接在i2c總線(xiàn)上的外設作為從設備。通信開(kāi)始都是由主設備發(fā)起的,在i2c總線(xiàn)上的每個(gè)設備都有一個(gè)7bit位的地址,稱(chēng)為i2c設備地址。
主設備如何發(fā)起開(kāi)始和停止通信信號?
在SCL線(xiàn)為高電平時(shí),將SDA線(xiàn)由高拉低,即發(fā)出一個(gè)start開(kāi)始信號;當SCL為高電平時(shí),將SDA由低拉高,即發(fā)送一個(gè)stop停止信號;那么這些操作都是由主設備的I2C控制器完成的。
I2C總線(xiàn)上有很多的設備,如何保證一對一的通信?
在I2C總線(xiàn)上的每個(gè)設備都有一個(gè)7bit位的地址,在I2C總線(xiàn)處于空閑狀態(tài)時(shí),如果有主設備想發(fā)起通信,那么將由它先發(fā)出一個(gè)start信號占有總線(xiàn),緊接著(zhù)發(fā)送這個(gè)主設備想要進(jìn)行通信的從設備的7bit位的地址,這個(gè)地址在I2C總線(xiàn)上處于廣播狀態(tài),即總線(xiàn)上的所有設備都能看到這個(gè)地址,如果某一個(gè)從設備發(fā)現總線(xiàn)上傳輸的地址和自己的設備地址一樣,那么就發(fā)送一個(gè)應答信號,這時(shí)主從設備間的通信就建立了,這個(gè)時(shí)候I2C總線(xiàn)將處于busy狀態(tài),其他的設備無(wú)法再使用總線(xiàn),從而在總線(xiàn)上建立了一個(gè)一對一的通信。當通信結束時(shí),由主設備發(fā)送一個(gè)stop信號,釋放總線(xiàn),其他的設備就可以再次占用總線(xiàn)通信了。
I2C上的主從設備如何通信?
在I2C總線(xiàn)上傳輸的數據都是8bit位為單位的,所以當主機要往從機寫(xiě)數據時(shí)時(shí)序如下:
發(fā)送start信號
發(fā)送7位地址+1個(gè)讀寫(xiě)位0(0表示寫(xiě),1表示讀)
從機收到地址后,發(fā)送ACK應答信號
主機收到應答信號后發(fā)送要寫(xiě)的8位數據
若從機收到主機發(fā)送的數據,發(fā)送ACK應答信號
如果主機要繼續寫(xiě),那么回到步驟4,如果寫(xiě)完了那么發(fā)送stop信號,終止通信
當主機要從從機讀取數據時(shí)時(shí)序如下:
發(fā)送start信號
發(fā)送7位地址+1個(gè)讀寫(xiě)位1(0表示寫(xiě),1表示讀)
從機收到地址后,發(fā)送ACK應答信號
主機收到應答信號后等待接收從機的數據
從機發(fā)送主機要讀取的數據
若主機收到從機發(fā)送的數據,發(fā)送ACK應答信號
如果主機要繼續讀,那么回到步驟4,如果讀完了那么發(fā)送stop信號,終止通信
那么在具體的使用場(chǎng)景中是什么樣子呢?從機設備內部往往有很多寄存器,如何讀寫(xiě)這些寄存器呢?以RPR0521這個(gè)sensor作為從設備的實(shí)例進(jìn)行分析:
主機寫(xiě)RPR0521中某個(gè)寄存器(寄存器的地址是8位的,寄存器中數據也是8位的)
主機發(fā)送完7位的從機地址和寫(xiě)位
主機發(fā)送8位的要寫(xiě)的從機的內部寄存器地址
從機收到后發(fā)送ACK
主機收到ACK后,然后發(fā)送要往這個(gè)寄存器寫(xiě)的數據
如果主機不繼續寫(xiě)數據就直接發(fā)送stop,如果還要往下一個(gè)寄存器繼續寫(xiě)(寄存器地址必須連續)那么回到步驟4發(fā)送下一個(gè)數據,直到寫(xiě)完發(fā)送stop
主機讀RPR0521中某個(gè)寄存器的值(寄存器的地址是8位的,寄存器中數據也是8位的)
主機發(fā)送完7位的從機地址和寫(xiě)位(一定要注意,先寫(xiě)然后讀)
主機發(fā)送8位的要讀的從機的內部寄存器地址(用于確定要讀的寄存器的地址)
從機收到后發(fā)送ACK
主機收到ACK后發(fā)送7位的從機地址和讀位,然后等待接收數據
主機收到ACK和從機發(fā)送過(guò)來(lái)的數據
如果主機不讀了就發(fā)送stop,如果繼續讀就回到步驟5(從機會(huì )自動(dòng)發(fā)送連續寄存器的數據)
常用debug手段
在實(shí)際項目中,通常會(huì )出現讀不到數據,那么我們就需要debug,最常見(jiàn)的debug手段就是使用示波器抓時(shí)序,下圖是I2C數據傳輸的時(shí)序:
SDA的數據在SCL位高電平時(shí)保持穩定,在SCL為低電平時(shí)數據改變,所以我們應該在時(shí)鐘周期的高電平期間讀取有效數據進(jìn)行分析。
以上是我總結的I2C總線(xiàn)的基本協(xié)議,如有不足歡迎指出,謝謝閱讀!
*博客內容為網(wǎng)友個(gè)人發(fā)布,僅代表博主個(gè)人觀(guān)點(diǎn),如有侵權請聯(lián)系工作人員刪除。