2. 寫操作步驟:
2.1 主機(jī)發(fā)起通信,按約定依次寫入command、要寫入的從機(jī)寄存器地址address和要寫入的數(shù)據(jù)data;
2.2 從機(jī)firmware要做的處理:
2.2.1 分別提取command、address和data;
2.2.2 根據(jù)command做出判斷(本例中則判斷是寫入還是讀?。?/p>
2.2.3 將data寫入與接收到的address對應(yīng)的寄存器。(這個步驟可以使用指針)。

4、主機(jī)發(fā)送數(shù)據(jù)流程
?。?)主機(jī)在檢測到總線為“空閑狀態(tài)”(即 SDA、SCL 線均為高電平)時,發(fā)送一個啟動信號“S”,開始一次通信的開始
?。?)主機(jī)接著發(fā)送一個命令字節(jié)。該字節(jié)由 7 位的外圍器件地址和 1 位讀寫控制位 R/W組成(此時 R/W=0)
?。?)相對應(yīng)的從機(jī)收到命令字節(jié)后向主機(jī)回饋應(yīng)答信號 ACK(ACK=0)
?。?)主機(jī)收到從機(jī)的應(yīng)答信號后開始發(fā)送第一個字節(jié)的數(shù)據(jù)
?。?)從機(jī)收到數(shù)據(jù)后返回一個應(yīng)答信號 ACK
?。?)主機(jī)收到應(yīng)答信號后再發(fā)送下一個數(shù)據(jù)字節(jié)
?。?)當(dāng)主機(jī)發(fā)送最后一個數(shù)據(jù)字節(jié)并收到從機(jī)的 ACK 后,通過向從機(jī)發(fā)送一個停止信號P結(jié)束本次通信并釋放總線。從機(jī)收到P信號后也退出與主機(jī)之間的通信

注意:①主機(jī)通過發(fā)送地址碼與對應(yīng)的從機(jī)建立了通信關(guān)系,而掛接在總線上的其它從機(jī)雖然同時也收到了地址碼,但因?yàn)榕c其自身的地址不相符合,因此提前退出與主機(jī)的通信;②主機(jī)的一次發(fā)送通信,其發(fā)送的數(shù)據(jù)數(shù)量不受限制。主機(jī)是通過 P 信號通知發(fā)送的結(jié)束,從機(jī)收到 P 信號后退出本次通信;③主機(jī)的每一次發(fā)送后都是通過從機(jī)的 ACK 信號了解從機(jī)的接收狀況,如果應(yīng)答錯誤則重發(fā)。
5、主機(jī)接收數(shù)據(jù)流程
?。?)主機(jī)發(fā)送啟動信號后,接著發(fā)送命令字節(jié)(其中 R/W=1)
?。?)對應(yīng)的從機(jī)收到地址字節(jié)后,返回一個應(yīng)答信號并向主機(jī)發(fā)送數(shù)據(jù)
(3)主機(jī)收到數(shù)據(jù)后向從機(jī)反饋一個應(yīng)答信號
?。?)從機(jī)收到應(yīng)答信號后再向主機(jī)發(fā)送下一個數(shù)據(jù)
(5)當(dāng)主機(jī)完成接收數(shù)據(jù)后,向從機(jī)發(fā)送一個“非應(yīng)答信號(ACK=1)”,從機(jī)收到ASK=1 的非應(yīng)答信號后便停止發(fā)送
?。?)主機(jī)發(fā)送非應(yīng)答信號后,再發(fā)送一個停止信號,釋放總線結(jié)束通信

注意:主機(jī)所接收數(shù)據(jù)的數(shù)量是由主機(jī)自身決定,當(dāng)發(fā)送“非應(yīng)答信號/A”時從機(jī)便結(jié)束傳送并釋放總線(非應(yīng)答信號的兩個作用:前一個數(shù)據(jù)接收成功,停止從機(jī)的再次發(fā)送)。
6、總線死鎖原因分析
I2C總線寫操作過程中,主機(jī)在產(chǎn)生啟動信號后控制SCL產(chǎn)生8個時鐘脈沖,然后拉低SCL信號為低電平,在這個時候,從機(jī)輸出應(yīng)答信號,將SDA信號拉為低電平。如果這個時候主機(jī)異常復(fù)位,SCL就會被釋放為高電平。此時,如果從機(jī)沒有復(fù)位,就會繼續(xù)I2C的應(yīng)答,將SDA一直拉為低電平,直到SCL變?yōu)榈碗娖剑艜Y(jié)束應(yīng)答信號。而對于主機(jī)來說,復(fù)位后檢測SCL和SDA信號,如果發(fā)現(xiàn)SDA信號為低電平,則會認(rèn)為I2C總線被占用,會一直等待SCL和SDA信號變?yōu)楦唠娖健_@樣,主機(jī)等待從機(jī)釋放SDA信號,而同時從機(jī)又在等待主機(jī)將SCL信號拉低以釋放應(yīng)答信號,兩者相互等待,I2C總線進(jìn)人一種死鎖狀態(tài)。同樣,當(dāng)I2C進(jìn)行讀操作時,從機(jī)應(yīng)答后輸出數(shù)據(jù),如果在這個時刻主機(jī)異常復(fù)位而此時從機(jī)輸出的數(shù)據(jù)位正好為0,也會導(dǎo)致I2C總線進(jìn)入死鎖狀態(tài)。
解決方案通常有如下幾種:
(1)將從機(jī)的電源設(shè)計為可控,當(dāng)發(fā)生總線死鎖的時將從機(jī)復(fù)位
?。?)可以在從機(jī)的程序中加入監(jiān)測功能,如果總線長時間被拉低則釋放對總線的控制
?。?)在主機(jī)中增加I2C總線恢復(fù)程序。每次主機(jī)復(fù)位后,如果檢測到SDA被拉低,則控制SCL產(chǎn)生《=9個時鐘脈沖(針對8位數(shù)據(jù)的情況),每發(fā)送一個時鐘脈沖就檢測SDA是否被釋放,如果SDA已經(jīng)被釋放就再模擬產(chǎn)生一個停止信號,這樣從機(jī)就可以完成被掛起的讀寫操作,從死鎖狀態(tài)中恢復(fù)過來。這種方法有一定的局限性,因?yàn)榇蟛糠种鳈C(jī)的I2C模塊由內(nèi)置的硬件電路來實(shí)現(xiàn),軟件并不能夠直接控制SCL信號模擬產(chǎn)生需要時鐘脈沖。
掛在I2C總線上的EEPROM設(shè)備
EEPROM稱為電擦除式只讀存儲器,一般容量很小、用于保存產(chǎn)品的固化參數(shù),此次跟我狹路相逢的是一款來自ATMEL公司的AT24C512B,總?cè)萘繛?4K,支持以頁的方式寫入數(shù)據(jù),頁大小128字節(jié),以下是這款設(shè)備的相關(guān)信息和操作方法(其他型號類同):
硬件連接。在AT24C512B硬件連接中,跟軟件編程相關(guān)的引腳有三個,除了連接在I2C總線上的時鐘線(SCL)、數(shù)據(jù)線(SDA)引腳之外,還有一個寫保護(hù)引腳(WP)連接在GPIO上。
尋址方式。EEPROM可以讓你精確地訪問到每一字節(jié),AT24C512B采用16位的尋址方式共計可以訪問65536字節(jié)的地址空間。
讀寫時序。AT24C512B支持的寫操作有單字節(jié)寫入、按頁寫入,支持的讀操作有隨機(jī)單字節(jié)或連接讀取、當(dāng)前位置單字節(jié)或連續(xù)讀取,EEPROM一般在電路中做從設(shè)備,我此次面對的也是,以下是主設(shè)備對EEPROM進(jìn)行各種操作的操作方法:
單字節(jié)寫入:START -》 發(fā)送從設(shè)備地址(寫控制碼) -》 處理Ack -》 發(fā)送字節(jié)地址 -》 處理Ack [-》 發(fā)送1字節(jié)數(shù)據(jù) -》 處理Ack] -》 STOP。
按頁寫入:將單字節(jié)寫入的[ ]中的操作重復(fù)進(jìn)行128次即可實(shí)現(xiàn)。
隨機(jī)單字節(jié)讀取:START -》 發(fā)送從設(shè)備地址(寫控制碼) -》 處理Ack -》 發(fā)送字節(jié)地址 -》 處理Ack -》 START -》 發(fā)送器件地址(讀控制碼) -》 處理Ack -》 接收1字節(jié)數(shù)據(jù) -》 STOP。
隨機(jī)連續(xù)讀取:在隨機(jī)單字節(jié)讀取操作的STOP信號發(fā)送之前,加入若干個 [-》 發(fā)送Ack -》 接收1字節(jié)數(shù)據(jù)] 即可實(shí)現(xiàn)。
當(dāng)前位置單字節(jié)讀?。篠TART -》 發(fā)送從設(shè)備地址(讀控制碼) -》 處理Ack -》 發(fā)送字節(jié)地址 -》 處理Ack -》 接收1字節(jié)數(shù)據(jù) -》 STOP。當(dāng)前指的是之前進(jìn)行過讀取操作但是沒有發(fā)送STOP信號,EEPROM芯片內(nèi)部指針?biāo)诘奈恢眉礊楫?dāng)前位置。
當(dāng)前位置連續(xù)讀?。涸诋?dāng)前位置單節(jié)讀取操作的STOP信號發(fā)送之前,加入若干個 [-》 發(fā)送Ack -》 接收1字節(jié)數(shù)據(jù)] 即可實(shí)現(xiàn)。
關(guān)于EEPROM的按頁寫入。為提高數(shù)據(jù)寫入效率,有的EEPROM設(shè)備用一個內(nèi)部的RAM來提供按頁寫入的功能,進(jìn)行寫操作的時候,先記錄下要寫入的首地址,然后將接收到的數(shù)據(jù)都緩存在RAM中,在接收到STOP信號時再把緩存數(shù)據(jù)一次性保存到先前記錄的地址處。
有兩個需要注意的問題:(a)、如果寫入的數(shù)據(jù)超過一頁的長度,將發(fā)生回卷,即從RAM的0地址處進(jìn)行數(shù)據(jù)覆蓋。(b)、如果頁大小為128字節(jié),即0-127字節(jié)為第一頁、128-255為第二頁,即頁的邊界位置是絕對的,而不是從寫入數(shù)據(jù)的起始位置開始計算。
在進(jìn)行數(shù)據(jù)讀取操作沒有頁的問題,可以從任意位置開始讀取任意大小的數(shù)據(jù),超過EEPROM總?cè)萘繒r發(fā)生回卷。
電子發(fā)燒友App






評論