關于I2C的總結
1——————
最先遇到的問題是AT24C02的操作時序,AT24C02內部有一個指針,指向儲存空間的某一個字節,另外AT24C系列支持頁操作,對于AT24C02一個頁是8字節,也就是說地址的高5位是頁地址,在同一次寫入中,頁地址不變,低3位地址一次增加,當增加到7之后再加1就變成0了,而由于頁地址不變,相當于指針回到了頁首,如果繼續寫那前面的內容會被覆蓋。寫數據的時序,先是I2C的開始信號,發送設備地址,之后寫入希望寫入的數據地址,然后依次寫入數據。當然,可以只寫一個字節的數據。
對于讀取,是不存在頁的概念的,時序是先發送啟動信號,然后發送設備地址(注意,是寫設備的時候的地址,也就是說最低位是1),接著發送數據地址,完了之后重新發送一次啟動信號,接著就可以讀取了,讀取完一個字節的數據后要發送一個ACK,對于最后一個字節的數據要發送一個NACK來告訴AT24C數據已經接收完畢,之后發送結束信號斷開連接即可。也可以只接收一個數據,這時候一個ACK都沒有,第一次接收好直接發送一個NACK。
24C02的內部有連續的子地址空間,對這些空間進行n個字節的連續讀/寫時,都具有地址自動加1功能。只要設定好要讀/寫的器件內起始子地址及字節數,就能完成整個操作。
注意:對于24C02連續寫的字節數不應超過頁容量8,一次連續寫所形成的總線傳送結束后(主機發出停止信號后),24C02執行內部擦寫過程,大約需要10ms左右,24C02不再應答主器件的任何請求。
24C02內有一個8位的地址計數器,連續讀操作時,24C02每次輸出一個數據字節后,地址計數器自動加1,當地址計數器加到255,并輸出一個字節數據后,地址計數器將翻轉到0,并繼續輸出數據字節,這樣整個存儲區域可以在一個讀操作內全部讀完。
#define SLAW 0xA0
uchar delay(uchar j)
{ uchar k,l;
for(l=0;l<=j;l++)
for(k=0;k<=250;k++);
return 0;
}
void main()
{
uchar sbuf[5]={0x00,0x12,0x55,0x30,0x12};
uchar rbuf[5];
I2C_SendStr(SLAW,0x10,tbuf,0x5);
delay(100);
I2C_RcvStr(SLAW,0x10,rbuf,0x5);
while(1);
}
}
2——————
在次我只發表對I2C確認信號的看法,至于它的一整套時序就不多羅嗦了。
1)MASTER向SLAVE發送數據:
MASTER沒向SLAVE端發送8位數據后,就會將SDA置1,等待SLAVE端的確認;SLAVE端如果正確接受到數據,就會自動將SDA置0。我們程序員所能做的只能是檢測確認信號,即每發送完8位數據后就檢測一次SDA的狀態,如果是0,則讓程序繼續往下執行,如果是1則強迫MASTER將剛才的8位數據再發送一遍;當然,如果SDA一直是1,也就是SLAVE一直未能正確接受到數據,我們也不能一直讓MASTER反復發送,要做TIMEOUT處理,以防系統死機!
2) MASTER從SLAVE讀取數據:
MASTER從SLAVE端讀取數據,情況與發送數據有所區別,在讀到最后8位數據時,要將SDA置1,也就是做UNACK動作,讓系統知道讀取數據到此結束;這個置1動作由程序員來做,而不是MASTER本身,因為數據讀到哪里結束,只有我們程序員知道!
3) 說明:MASTER 指主控制端,在一般系統中就是我們常說的單片機了;SLAVE是指具備I2C協議的專用IC,比如ATMEL的24系列(24C16、14C32等)和PHILPS的SAA711X系列(VIDEO DECODER)。


評論