stm32 IIC ACK與NACK的理解

參考自:http://blog.chinaunix.net/uid-16100003-id-3059814.html

關於IIC的響應問題對於每一個接收設備(從設備,slaver),當它被尋址後,都要求在接收到每一個字節後產生一個響應。因此,the master device 必須產生一個額外的時鐘脈衝(第九個脈衝)用以和這個響應位相關聯。

在這個脈衝期間,發出響應的從設備必須將SDA拉低並在時鐘脈衝的高電平期間保持住。這表示該設備給出了一個ACK。如果它不拉低SDA線,就表示不響應(NACK)。

另外,在從機(發送方)發送完最後一個字節後主設備(接收方)必須產生一個不響應位,用以通知從機(發送方)不要再發送信息了,這樣從機就知道該將SDA釋放了,而後,主機發出一個停止位給slaver。

總結下,IIC通訊中,SDA 和 SCL 都是有主機控制的,從設備只是能夠將SDA線拉低而已。對於SCL線,從機是沒有任何能力去控制的。從機只能被動跟隨SCL。

再說的清楚些:

主機發送數據到從機的狀態下:主機控制SCL信號線和SDA信號線,從機只是在SCL線爲高的時候去被動讀取SDA線。

主機讀取從機的數據的狀態下:主機來發出時鐘信號,從機只是保證在時鐘信號爲高電平的時候的SDA的狀態而已。

//----------------------------------------

補充@201108311142

SDA和SCL已經通過上拉電阻被上拉,master可以控制(拉低或者釋放)這兩條線,而slaver只能控制SDA線。當master發送數據時,master會適時地將SDA和SCL拉低或釋放(拉高)。確切的時序應該是這樣的:

當mater要發送一個start時,mater會將SDA拉低這就可以了,因爲此時的SCL一定是High。好了,一個start就這樣發出去了。而slaver也會發現這個start信號的發生,slaver便會準備好接收接下來的數據。緊接着,master要發送一個Byte的數據了一位一位的發出這8個bits。這時master會先將SCL拉低,然後在SCL爲低的狀態下將一個bit準備好放到SDA上(比如要發送一個 0,master就會通過拉低SDA來放好這個0),然後master會把SCL拉高(釋放),此時slaver會立刻檢測到SCL的變化,由此聰明的slaver便知道master已經將要發送的那個bit準備好了,slaver便會在這個SCL的高電平期間儘快(maser不會等你很久的哦)去讀取一下SDA,嗯讀到了一個0,slaver就把這個0放到自己的移位寄存器中待後續處理。master會在一個設定好的時間後把SCL再次拉低,然後在SCL爲低電平期間把下一個bit放到SDA上,然後再把SCL拉高,然後slaver在SCL的高電平期間再去讀SDA。。。。。如此反覆8次,一個Byte的傳輸便告結束。當這8個bit發完後,SCL是處於低電平的(被master拉低的),SDA是出於高電平的(master已經釋放了SDA)。

當一個字節發送完畢後,master會釋放SDA(拉高)並拉低SCL,此時slaver如果打算髮出一個ACK的話,它必須在這個SCL被master拉低的短暫時間內去主動將SDA拉低並保持住 (此前我們說過,SDA此時已經被master釋放,所以slaver纔有機會去拉低這個SDA)。master會在一個確定的時間後再次將SCL拉高,並在拉高的期間去讀取SDA線的狀態,如果讀到低電平,則認爲收到了來自slaver的響應(ACK),否則認爲slaver沒有響應(NACK)剛纔發送的那一個Byte這個過程就是我們說的i2c通訊中的第9個時鐘週期。當master讀完這個ACK / NACK 後,會再次將SCL拉低,用以通知slaver:第9個時鐘週期已經結束,你現在可以釋放SDA了。而此時master也可以向SDA上準備下一個Byte的第一個bit。繼而重複上述過程。。。。。或者,master也許想在接下來發送一個stop過去,那麼master會在這個SCL爲低的時間內將SDA拉低,而後再將SCL拉高,在SCL爲高的期間再將SDA釋放 (拉高) 。這樣,一個STOP位就產生了。你會發現此後的SDA和SCL都是高,這就是是所謂的總線空閒了!

一句話:SCL是單向的,由master控制。而SDA是雙向的,master可以控制,slaver也可以控制。

閱讀上述過程時,始終牢記:SDA上的數據必須在SCL爲高電平期間保持穩定,SDA上的數據只能在SCL爲低電平期間變化。(開始信號和結束信號例外)!

另外,需要注意的是,並非每傳輸8位數據之後,都會有ACK信號,有以下3種例外:

(1)當從機不能響應從機地址時(例如它正忙於其他事而無法相應I2C總線的操作,或者這個地址沒有對應的從機),在第9個SCL週期內SDA線沒有被拉低,即沒有ACK信號。這時,主機發出一個P信號終止傳輸或者重新發出一個S信號開始新的傳輸。

(2)如果從機接收器在傳輸過程中不能接收更多的數據時,它也不會發出ACK信號。這樣,主機就可以意識到這點,從而發出一個P信號終止傳輸或者發出一個S信號開始新的傳輸。

(3)主機接收器在接收到最後一個字節後,也不會發出ACK信號。於是,從機發送器釋放SDA線,以允許主機發出P信號結束傳輸。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章