在最近的編程過程中,會經常使用I2C來讀寫數據,用示波器來查看I2C的波形,所以想總結一下I2C中關於ACK和NACK的幾點東西。
I2C簡介
I2C是由Philips公司發明的一種串行數據通信協議,僅使用兩根信號線:SerialClock(簡稱SCL)和SerialData(簡稱SDA)。I2C是總線結構,1個Master,1個或多個Slave,各Slave設備以7位地址區分,地址后面再跟1位讀寫位,表示讀(=1)或者寫(=0),所以我們有時也可看到8位形式的設備地址,此時每個設備有讀、寫兩個地址,高7位地址其實是相同的。
I2C的數據格式
無數據:SCL=1,SDA=1;
開始位(Start):當SCL=1時,SDA由1向0跳變;
停止位(Stop):當SCL=1時,SDA由0向1跳變;
數據位:當SCL由0向1跳變時,由發送方控制SDA,此時SDA為有效數據,不可隨意改變SDA;
當SCL保持為0時,SDA上的數據可隨意改變;
地址位:定義同數據位,但只由Master發給Slave;
應答位(ACK):當發送方傳送完8位時,發送方釋放SDA,由接收方控制SDA,且SDA=0;
否應答位(NACK):當發送方傳送完8位時,發送方釋放SDA,由接收方控制SDA,且SDA=1。
當數據為單字節傳送時,格式為:
開始位,8位地址位(含1位讀寫位),應答,8位數據,應答,停止位。
當數據為一串字節傳送時,格式為:
開始位,8位地址位(含1位讀寫位),應答,8位數據,應答,8位數據,應答,……,8位數據,應答,停止位。
幾點注意事項
SCL一直由Master控制,SDA依照數據傳送的方向,讀數據時由Slave控制SDA,寫數據時由Master控制SDA。當8位數據傳送完畢之后,應答位或者否應答位的SDA控制權與數據位傳送時相反。
開始位“Start”和停止位“Stop”,只能由Master來發出。
地址的8位傳送完畢后,成功配置地址的Slave設備必須發送“ACK”。否則否則一定時間之后Master視為超時,將放棄數據傳送,發送“Stop”。
當寫數據的時候,Master每發送完8個數據位,Slave設備如果還有空間接受下一個字節應該回答“ACK”,Slave設備如果沒有空間接受更多的字節應該回答“NACK”,Master當收到“NACK”或者一定時間之后沒收到任何數據將視為超時,此時Master放棄數據傳送,發送“Stop”。
當讀數據的時候,Slave設備每發送完8個數據位,如果Master希望繼續讀下一個字節,Master應該回答“ACK”以提示Slave准備下一個數據,如果Master不希望讀取更多字節,Master應該回答“NACK”以提示Slave設備准備接收Stop信號。
當Master速度過快Slave端來不及處理時,Slave設備可以拉低SCL不放(SCL=0將發生“線與”)以阻止Master發送更多的數據。此時Master將視情況減慢或結束數據傳送。
在實際應用中,並沒有強制規定數據接收方必須對於發送的8位數據做出回應,尤其是在Master和Slave端都是用GPIO軟件模擬的方法來實現的情況下,編程者可以事先約定數據傳送的長度,slave不檢查NACK,有時可以起到減少系統開銷的效果。但是如果slave方是硬件i2c要求一定要標准的NACK,master方是GPIO軟件模擬i2c並沒有正確的發送NACK,就會出現“slave收不到stop”導致i2c掛死。
from: https://blog.csdn.net/liebecl/java/article/details/76563083