IIC 簡(jiǎn)介 IIC(Inter-Integrated Circuit)總線是一種由NXP(原PHILIPS)公司開(kāi)發(fā)的兩線式串行總線,用于連接微控制器及其外圍設(shè)備。多用于主控制器和從器件間的主從通信,在小數(shù)據(jù)量場(chǎng)合使用,傳輸距離短,任意時(shí)刻只能有一個(gè)主機(jī)等特性。 在 CPU 與被控 IC 之間、IC 與 IC 之間進(jìn)行雙向傳送,高速 IIC 總線一般可達(dá) 400kbps 以上。 PS: 這里要注意IIC是為了與低速設(shè)備通信而發(fā)明的,所以IIC的傳輸速率比不上SPI  IIC的物理層IIC一共有只有兩個(gè)總線: 一條是雙向的串行數(shù)據(jù)線SDA,一條是串行時(shí)鐘線SCL 所有接到I2C總線設(shè)備上的串行數(shù)據(jù)SDA都接到總線的SDA上,各設(shè)備的時(shí)鐘線SCL接到總線的SCL上。I2C總線上的每個(gè)設(shè)備都自己一個(gè)唯一的地址,來(lái)確保不同設(shè)備之間訪問(wèn)的準(zhǔn)確性。 ![[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來(lái)直接上傳(img-fxNfPPim-1586571859509)(C:\Users\48013\AppData\Roaming\Typora\typora-user-images\image-20200331212342296.png)]](http://image109.360doc.com/DownloadImg/2021/05/1015/221747906_2_2021051003351620)
IIC主要特點(diǎn): 通常我們?yōu)榱朔奖惆袸IC設(shè)備分為主設(shè)備和從設(shè)備,基本上誰(shuí)控制時(shí)鐘線(即控制SCL的電平高低變換)誰(shuí)就是主設(shè)備。** IIC主設(shè)備功能:主要產(chǎn)生時(shí)鐘,產(chǎn)生起始信號(hào)和停止信號(hào) IIC從設(shè)備功能:可編程的IIC地址檢測(cè),停止位檢測(cè) IIC的一個(gè)優(yōu)點(diǎn)是它支持多主控(multimastering), 其中任何一個(gè)能夠進(jìn)行發(fā)送和接收的設(shè)備都可以成為主總線。一個(gè)主控能夠控制信號(hào)的傳輸和時(shí)鐘頻率。當(dāng)然,在任何時(shí)間點(diǎn)上只能有一個(gè)主控。 支持不同速率的通訊速度,標(biāo)準(zhǔn)速度(最高速度100kHZ),快速(最高400kHZ) SCL和SDA都需要接上拉電阻 (大小由速度和容性負(fù)載決定一般在3.3K-10K之間) 保證數(shù)據(jù)的穩(wěn)定性,減少干擾。 IIC是半雙工,而不是全雙工 ,同一時(shí)間只可以單向通信 為了避免總線信號(hào)的混亂,要求各設(shè)備連接到總線的輸出端時(shí)必須是漏極開(kāi)路(OD)輸出或集電極開(kāi)路(OC)輸出。這一點(diǎn)在等下我們會(huì)講解
IIC的高阻態(tài)漏極開(kāi)路(Open Drain)即高阻狀態(tài),適用于輸入/輸出,其可獨(dú)立輸入/輸出低電平和高阻狀態(tài),若需要產(chǎn)生高電平,則需使用外部上拉電阻 高阻狀態(tài):高阻狀態(tài)是三態(tài)門(mén)電路的一種狀態(tài)。邏輯門(mén)的輸出除有高、低電平兩種狀態(tài)外,還有第三種狀態(tài)——高阻狀態(tài)的門(mén)電路。電路分析時(shí)高阻態(tài)可做開(kāi)路理解。 我們知道IIC的所有設(shè)備是接在一根總線上的,那么我們進(jìn)行通信的時(shí)候往往只是幾個(gè)設(shè)備進(jìn)行通信,那么這時(shí)候其余的空閑設(shè)備可能會(huì)受到總線干擾,或者干擾到總線,怎么辦呢? 為了避免總線信號(hào)的混亂,IIC的空閑狀態(tài)只能有外部上拉, 而此時(shí)空閑設(shè)備被拉到了高阻態(tài),也就是相當(dāng)于斷路, 整個(gè)IIC總線只有開(kāi)啟了的設(shè)備才會(huì)正常進(jìn)行通信,而不會(huì)干擾到其他設(shè)備。 
IIC器件地址: 每一個(gè)IIC器件都有一個(gè)器件地址,有的器件地址在出廠時(shí)地址就設(shè)定好了,用戶不可以更改,比如OV7670的地址為0x42。有的器件例如EEPROM,前四個(gè)地址已經(jīng)確定為1010,后三個(gè)地址是由硬件鏈接確定的,所以一IIC總線最多能連8個(gè)EEPROM芯片。 IIC物理層總結(jié):I2C 總線在物理連接上非常簡(jiǎn)單,分別由SDA(串行數(shù)據(jù)線)和SCL(串行時(shí)鐘線)及上拉電阻組成。通信原理是通過(guò)對(duì)SCL和SDA線高低電平時(shí)序的控制,來(lái)產(chǎn)生I2C總線協(xié)議所需要的信號(hào)進(jìn)行數(shù)據(jù)的傳遞。在總線空閑狀態(tài)時(shí),SCL和SDA被上拉電阻Rp拉高,使SDA和SCL線都保持高電平。 I2C通信方式為半雙工,只有一根SDA線,同一時(shí)間只可以單向通信,485也為半雙工,SPI和uart通信為全雙工。 主機(jī)和從機(jī)的概念: 主機(jī)就是負(fù)責(zé)整個(gè)系統(tǒng)的任務(wù)協(xié)調(diào)與分配,從機(jī)一般是通過(guò)接收主機(jī)的指令從而完成某些特定的任務(wù),主機(jī)和從機(jī)之間通過(guò)總線連接,進(jìn)行數(shù)據(jù)通訊。 發(fā)布主要命令的稱為主機(jī) 接受命令的稱為從機(jī)
半雙工和全雙工: IIC的協(xié)議層I2C 總線在傳送數(shù)據(jù)過(guò)程中共有三種類(lèi)型信號(hào), 它們分別是:開(kāi)始信號(hào)、結(jié)束信號(hào)和應(yīng)答信號(hào)。 開(kāi)始信號(hào):SCL 為高電平時(shí),SDA 由高電平向低電平跳變,開(kāi)始傳送數(shù)據(jù)。 結(jié)束信號(hào):SCL 為高電平時(shí),SDA 由低電平向高電平跳變,結(jié)束傳送數(shù)據(jù)。 應(yīng)答信號(hào):接收數(shù)據(jù)的 IC 在接收到 8bit 數(shù)據(jù)后,向發(fā)送數(shù)據(jù)的 IC 發(fā)出特定的低電平脈沖,表示已收到數(shù)據(jù)。CPU 向受控單元發(fā)出一個(gè)信號(hào)后,等待受控單元發(fā)出一個(gè)應(yīng)答信號(hào),CPU 接收到應(yīng)答信號(hào)后,根據(jù)實(shí)際情況作出是否繼續(xù)傳遞信號(hào)的判斷。若未收到應(yīng)答信號(hào),由判斷為受控單元出現(xiàn)故障。
這些信號(hào)中,起始信號(hào)是必需的,結(jié)束信號(hào)和應(yīng)答信號(hào),都可以不要。 IIC 總線時(shí)序圖
下面我們來(lái)詳細(xì)的介紹下IIC的通信協(xié)議流程: 初始(空閑)狀態(tài)因?yàn)镮IC的 SCL 和SDA 都需要接上拉電阻,保證空閑狀態(tài)的穩(wěn)定性 所以IIC總線在空閑狀態(tài)下SCL 和SDA都保持高電平 代碼: void IIC_init() //IIC初始化{
SCL=1; //首先把時(shí)鐘線拉高
delay_us(4);//延時(shí)函數(shù)
SDA=1; //在SCL為高的情況下把SDA拉高
delay_us(4); //延時(shí)函數(shù)}開(kāi)始信號(hào):SCL保持高電平,SDA由高電平變?yōu)榈碗娖胶螅訒r(shí)(>4.7us),SCL變?yōu)榈碗娖健?/strong> 
代碼表示: //產(chǎn)生IIC起始信號(hào)//1.先拉高SDA,再拉高SCL,空閑狀態(tài)//2.拉低SDAvoid IIC_Start() //啟動(dòng)信號(hào){
SDA=1; //確保SDA線為高電平
delay_us(5);
SCL=1; //確保SCL高電平
delay_us(5);
SDA=0; //在SCL為高時(shí)拉低SDA線,即為起始信號(hào)
delay_us(5);
}12345678910111213141516171819201234567891011121314151617181920 停止信號(hào)停止信號(hào):SCL保持高電平。SDA由低電平變?yōu)楦唠娖健?/strong> 
//產(chǎn)生IIC停止信號(hào)//1.先拉低SDA,再拉低SCL//2.拉高SCL//3.拉高SDA//4.停止接收數(shù)據(jù)void IIC_Stop(void){IIC_SCL=0;IIC_SDA=0; //STOP:當(dāng)SCL高時(shí),數(shù)據(jù)由低變高
delay_us(4);IIC_SCL=1; IIC_SDA=1; //發(fā)送I2C總線結(jié)束信號(hào)delay_us(4); }在起始條件產(chǎn)生后,總線處于忙狀態(tài),由本次數(shù)據(jù)傳輸?shù)闹鲝脑O(shè)備獨(dú)占,其他I2C器件無(wú)法訪問(wèn)總線;而在停止條件產(chǎn)生后,本次數(shù)據(jù)傳輸?shù)闹鲝脑O(shè)備將釋放總線,總線再次處于空閑狀態(tài)。 
數(shù)據(jù)有效性IIC信號(hào)在數(shù)據(jù)傳輸過(guò)程中,當(dāng)SCL=1高電平時(shí),數(shù)據(jù)線SDA必須保持穩(wěn)定狀態(tài),不允許有電平跳變,只有在時(shí)鐘線上的信號(hào)為低電平期間,數(shù)據(jù)線上的高電平或低電平狀態(tài)才允許變化。 SCL=1時(shí) 數(shù)據(jù)線SDA的任何電平變換會(huì)看做是總線的起始信號(hào)或者停止信號(hào)。 也就是在IIC傳輸數(shù)據(jù)的過(guò)程中,SCL時(shí)鐘線會(huì)頻繁的轉(zhuǎn)換電平,以保證數(shù)據(jù)的傳輸 

應(yīng)答信號(hào)每當(dāng)主機(jī)向從機(jī)發(fā)送完一個(gè)字節(jié)的數(shù)據(jù),主機(jī)總是需要等待從機(jī)給出一個(gè)應(yīng)答信號(hào),以確認(rèn)從機(jī)是否成功接收到了數(shù)據(jù), 應(yīng)答信號(hào):主機(jī)SCL拉高,讀取從機(jī)SDA的電平,為低電平表示產(chǎn)生應(yīng)答 
**每發(fā)送一個(gè)字節(jié)(8個(gè)bit)**在一個(gè)字節(jié)傳輸?shù)?個(gè)時(shí)鐘后的第九個(gè)時(shí)鐘期間,接收器接收數(shù)據(jù)后必須回一個(gè)ACK應(yīng)答信號(hào)給發(fā)送器,這樣才能進(jìn)行數(shù)據(jù)傳輸。 應(yīng)答出現(xiàn)在每一次主機(jī)完成8個(gè)數(shù)據(jù)位傳輸后緊跟著的時(shí)鐘周期,低電平0表示應(yīng)答,1表示非應(yīng)答, 
//主機(jī)產(chǎn)生應(yīng)答信號(hào)ACK//1.先拉低SCL,再拉低SDA//2.拉高SCL//3.拉低SCL## 標(biāo)題void I2C_Ack(void){
IIC_SCL=0; //先拉低SCL,使得SDA數(shù)據(jù)可以發(fā)生改變
IIC_SDA=0;
delay_us(2);
IIC_SCL=1;
delay_us(5);
IIC_SCL=0;}//主機(jī)不產(chǎn)生應(yīng)答信號(hào)NACK//1.先拉低SCL,再拉高SDA//2.拉高SCL//3.拉低SCLvoid I2C_NAck(void){
IIC_SCL=0; //先拉低SCL,使得SDA數(shù)據(jù)可以發(fā)生改變
IIC_SDA=1; //拉高SDA,不產(chǎn)生應(yīng)答信號(hào)
delay_us(2);
IIC_SCL=1;
delay_us(5);
IIC_SCL=0;}12345678910111213141516171819202122232425262728291234567891011121314151617181920212223242526272829 IIC數(shù)據(jù)傳送數(shù)據(jù)傳送格式SDA線上的數(shù)據(jù)在SCL時(shí)鐘“高”期間必須是穩(wěn)定的,只有當(dāng)SCL線上的時(shí)鐘信號(hào)為低時(shí),數(shù)據(jù)線上的“高”或“低”狀態(tài)才可以改變。輸出到SDA線上的每個(gè)字節(jié)必須是8位,數(shù)據(jù)傳送時(shí),先傳送最高位(MSB),每一個(gè)被傳送的字節(jié)后面都必須跟隨一位應(yīng)答位(即一幀共有9位)。 當(dāng)一個(gè)字節(jié)按數(shù)據(jù)位從高位到低位的順序傳輸完后,緊接著從設(shè)備將拉低SDA線,回傳給主設(shè)備一個(gè)應(yīng)答位ACK, 此時(shí)才認(rèn)為一個(gè)字節(jié)真正的被傳輸完成 ,如果一段時(shí)間內(nèi)沒(méi)有收到從機(jī)的應(yīng)答信號(hào),則自動(dòng)認(rèn)為從機(jī)已正確接收到數(shù)據(jù)。 
IIC寫(xiě)數(shù)據(jù): 
多數(shù)從設(shè)備的地址為7位或者10位,一般都用七位。 八位設(shè)備地址=7位從機(jī)地址+讀/寫(xiě)地址, 再給地址添加一個(gè)方向位位用來(lái)表示接下來(lái)數(shù)據(jù)傳輸?shù)姆较颍?/p> IIC的每一幀數(shù)據(jù)由9bit組成, 如果是發(fā)送數(shù)據(jù),則包含 8bit數(shù)據(jù)+1bit ACK, 如果是設(shè)備地址數(shù)據(jù),則8bit包含7bit設(shè)備地址 1bit方向  在起始信號(hào)后必須傳送一個(gè)從機(jī)的地址(7位) 1~7位為7位接收器件地址,第8位為讀寫(xiě)位,用“0”表示主機(jī)發(fā)送數(shù)據(jù)(W),“1”表示主機(jī)接收數(shù)據(jù) (R), 第9位為ACK應(yīng)答位,緊接著的為第一個(gè)數(shù)據(jù)字節(jié),然后是一位應(yīng)答位,后面繼續(xù)第2個(gè)數(shù)據(jù)字節(jié)。
IIC發(fā)送一個(gè)字節(jié)數(shù)據(jù): //IIC發(fā)送一個(gè)字節(jié)//返回從機(jī)有無(wú)應(yīng)答//1,有應(yīng)答//0,無(wú)應(yīng)答 //IIC_SCL=0;//在SCL上升沿時(shí)準(zhǔn)備好數(shù)據(jù),進(jìn)行傳送數(shù)據(jù)時(shí),拉高拉低SDA,因?yàn)閭鬏斠粋€(gè)字節(jié),一個(gè)SCL脈沖里傳輸一個(gè)位。//數(shù)據(jù)傳輸過(guò)程中,數(shù)據(jù)傳輸保持穩(wěn)定(在SCL高電平期間,SDA一直保持穩(wěn)定,沒(méi)有跳變)//只有當(dāng)SCL被拉低后,SDA才能被改變//總結(jié):在SCL為高電平期間,發(fā)送數(shù)據(jù),發(fā)送8次數(shù)據(jù),數(shù)據(jù)為1,SDA被拉高,數(shù)據(jù)為0,SDA被拉低。//傳輸期間保持傳輸穩(wěn)定,所以數(shù)據(jù)線僅可以在時(shí)鐘SCL為低電平時(shí)改變。void IIC_Send_Byte(u8 txd){
u8 t;
SDA_OUT();
IIC_SCL=0;//拉低時(shí)鐘開(kāi)始數(shù)據(jù)傳輸
for(t=0;t<8;t++)
{
//IIC_SDA=(txd&0x80)>>7; //獲取最高位
//獲取數(shù)據(jù)的最高位,然后左移7位
//如果某位為1,則SDA為1,否則相反
if((txd&0x80)>>7)
IIC_SDA=1;
else
IIC_SDA=0;
txd<<=1;
delay_us(2);
IIC_SCL=1;
delay_us(2);
IIC_SCL=0;
delay_us(2);
} }1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
IIC讀取一個(gè)字節(jié)數(shù)據(jù): //讀1個(gè)字節(jié),ack=1時(shí),發(fā)送ACK,ack=0,發(fā)送nACK u8 IIC_Read_Byte(unsigned char ack){unsigned char i,receive=0;SDA_IN(); //SDA設(shè)置為輸入
for(i=0;i<8;i++ ){
IIC_SCL=0;
delay_us(2);IIC_SCL=1;
receive<<=1;
if(READ_SDA)receive++; delay_us(1);
}
if (!ack)
IIC_NAck(); //發(fā)送nACK
else
IIC_Ack(); //發(fā)送ACK
return receive;}1234567891011121314151617181920212212345678910111213141516171819202122 IIC發(fā)送數(shù)據(jù) 
Start: IIC開(kāi)始信號(hào),表示開(kāi)始傳輸。 DEVICE_ADDRESS:: 從設(shè)備地址,就是7位從機(jī)地址 R/W: W(write)為寫(xiě),R(read)為讀 ACK: 應(yīng)答信號(hào) WORD_ADDRESS : 從機(jī)中對(duì)應(yīng)的寄存器地址 比方說(shuō)訪問(wèn) OLED中的 某個(gè)寄存器 DATA: 發(fā)送的數(shù)據(jù) STOP: 停止信號(hào)。結(jié)束IIC 主機(jī)要向從機(jī)寫(xiě)數(shù)據(jù)時(shí): 主機(jī)首先產(chǎn)生START信號(hào) 然后緊跟著發(fā)送一個(gè)從機(jī)地址,這個(gè)地址共有7位,緊接著的第8位是數(shù)據(jù)方 向位(R/W),0表示主機(jī)發(fā)送數(shù)據(jù)(寫(xiě)),1表示主機(jī)接收數(shù)據(jù)(讀) 主機(jī)發(fā)送地址時(shí),總線上的每個(gè)從機(jī)都將這7位地址碼與自己的地址進(jìn)行比較,若相同,則認(rèn)為自己正在被主機(jī)尋址,根據(jù)R/T位將自己確定為發(fā)送器和接收器 這時(shí)候主機(jī)等待從機(jī)的應(yīng)答信號(hào)(A) 當(dāng)主機(jī)收到應(yīng)答信號(hào)時(shí),發(fā)送要訪問(wèn)從機(jī)的那個(gè)地址, 繼續(xù)等待從機(jī)的應(yīng)答信號(hào) 當(dāng)主機(jī)收到應(yīng)答信號(hào)時(shí),發(fā)送N個(gè)字節(jié)的數(shù)據(jù),繼續(xù)等待從機(jī)的N次應(yīng)答信號(hào), 主機(jī)產(chǎn)生停止信號(hào),結(jié)束傳送過(guò)程。
IIC讀數(shù)據(jù): 主機(jī)要從從機(jī)讀數(shù)據(jù)時(shí)
主機(jī)首先產(chǎn)生START信號(hào) 然后緊跟著發(fā)送一個(gè)從機(jī)地址,注意此時(shí)該地址的第8位為0,表明是向從機(jī)寫(xiě)命令, 這時(shí)候主機(jī)等待從機(jī)的應(yīng)答信號(hào)(ACK) 當(dāng)主機(jī)收到應(yīng)答信號(hào)時(shí),發(fā)送要訪問(wèn)的地址,繼續(xù)等待從機(jī)的應(yīng)答信號(hào), 當(dāng)主機(jī)收到應(yīng)答信號(hào)后,主機(jī)要改變通信模式(主機(jī)將由發(fā)送變?yōu)榻邮?,從機(jī)將由接收變?yōu)榘l(fā)送)所以主機(jī)重新發(fā)送一個(gè)開(kāi)始start信號(hào),然后緊跟著發(fā)送一個(gè)從機(jī)地址,注意此時(shí)該地址的第8位為1,表明將主機(jī)設(shè) 置成接收模式開(kāi)始讀取數(shù)據(jù), 這時(shí)候主機(jī)等待從機(jī)的應(yīng)答信號(hào),當(dāng)主機(jī)收到應(yīng)答信號(hào)時(shí),就可以接收1個(gè)字節(jié)的數(shù)據(jù),當(dāng)接收完成后,主機(jī)發(fā)送非應(yīng)答信號(hào),表示不在接收數(shù)據(jù) 主機(jī)進(jìn)而產(chǎn)生停止信號(hào),結(jié)束傳送過(guò)程。
以AT24C02為例子24C02是一個(gè)2K Bit的串行EEPROM存儲(chǔ)器(掉電不丟失),內(nèi)部含有256個(gè)字節(jié)。在24C02里面有一個(gè)8字節(jié)的頁(yè)寫(xiě)緩沖器。  A0,A1,A2:硬件地址引腳 WP:寫(xiě)保護(hù)引腳,接高電平只讀,接地允許讀和寫(xiě) SCL和SDA:IIC總線 可 以看出對(duì)于不同大小的24Cxx,具有不同的從器件地址。由于24C02為2k容量,也就是說(shuō)只需要參考圖中第一行的內(nèi)容:  芯片的尋址: AT24C設(shè)備地址為如下,前四位固定為1010,A2~A0為由管腳電平。AT24CXX EEPROM Board模塊中默認(rèn)為接地。A2~A0為000,最后一位表示讀寫(xiě)操作。所以AT24Cxx的讀地址為0xA1,寫(xiě)地址為0xA0。 也就是說(shuō)如果是 寫(xiě)24C02的時(shí)候,從器件地址為10100000(0xA0); 讀24C02的時(shí)候,從器件地址為10100001(0xA1)。 片內(nèi)陸址尋址: 芯片尋址可對(duì)內(nèi)部256B中的任一個(gè)進(jìn)行讀/寫(xiě)操作,其尋址范圍為00~FF,共256個(gè)尋址單位。 對(duì)應(yīng)的修改 A2A1A0 三位數(shù)據(jù)即可  向AT24C02中寫(xiě)數(shù)據(jù)  操作時(shí)序: MCU先發(fā)送一個(gè)開(kāi)始信號(hào)(START)啟動(dòng)總線 接著跟上首字節(jié),發(fā)送器件寫(xiě)操作地址(DEVICE ADDRESS)+寫(xiě)數(shù)據(jù)(0xA0) 等待應(yīng)答信號(hào)(ACK) 發(fā)送數(shù)據(jù)的存儲(chǔ)地址。24C02一共有256個(gè)字節(jié)的存儲(chǔ)空間,地址從0x00~0xFF,想把數(shù)據(jù)存儲(chǔ)>在哪個(gè)位置,此刻寫(xiě)的就是哪個(gè)地址。 發(fā)送要存儲(chǔ)的數(shù)據(jù)第一字節(jié)、第二字節(jié)、…注意在寫(xiě)數(shù)據(jù)的過(guò)程中,E2PROM每個(gè)字節(jié)都會(huì)>回應(yīng)一個(gè)“應(yīng)答位0”,老告訴我們寫(xiě)E2PROM數(shù)據(jù)成功,如果沒(méi)有回應(yīng)答位,說(shuō)明寫(xiě)入不成功。 發(fā)送結(jié)束信號(hào)(STOP)停止總線
注意: 在寫(xiě)數(shù)據(jù)的過(guò)程中,每成功寫(xiě)入一個(gè)字節(jié),E2PROM存儲(chǔ)空間的地址就會(huì)自動(dòng)加1,當(dāng)加到0xFF后,再寫(xiě)一個(gè)字節(jié),地址就會(huì)溢出又變成0x00。 寫(xiě)數(shù)據(jù)的時(shí)候需要注意,E2PROM是先寫(xiě)到緩沖區(qū),然后再“搬運(yùn)到”到掉電非易失區(qū)。所以這個(gè)過(guò)程需要一定的時(shí)間,AT24C02這個(gè)過(guò)程是不超過(guò)5ms! 所以,當(dāng)我們?cè)趯?xiě)多個(gè)字節(jié)時(shí),寫(xiě)入一個(gè)字節(jié)之后,再寫(xiě)入下一個(gè)字節(jié)之前,必須延時(shí)5ms才可以
從AT24C02中讀數(shù)據(jù) 讀當(dāng)前地址的數(shù)據(jù)  2、讀隨機(jī)地址的數(shù)據(jù)  MCU先發(fā)送一個(gè)開(kāi)始信號(hào)(START)啟動(dòng)總線 接著跟上首字節(jié),發(fā)送器件寫(xiě)操作地址(DEVICE ADDRESS)+寫(xiě)數(shù)據(jù)(0xA0) 注意:這里寫(xiě)操作是為了要把所要讀的數(shù)據(jù)的存儲(chǔ)地址先寫(xiě)進(jìn)去,告訴E2PROM要讀取哪個(gè)地址的數(shù)據(jù)。 發(fā)送要讀取內(nèi)存的地址(WORD ADDRESS),通知E2PROM讀取要哪個(gè)地址的信息。 重新發(fā)送開(kāi)始信號(hào)(START) 發(fā)送設(shè)備讀操作地址(DEVICE ADDRESS)對(duì)E2PROM進(jìn)行讀操作 (0xA1) E2PROM會(huì)自動(dòng)向主機(jī)發(fā)送數(shù)據(jù),主機(jī)讀取從器件發(fā)回的數(shù)據(jù),在讀一個(gè)字節(jié)后,MCU會(huì)回應(yīng)一個(gè)應(yīng)答信號(hào)(ACK)后,E2PROM會(huì)繼續(xù)傳輸下一個(gè)地址的數(shù)據(jù),MCU不斷回應(yīng)應(yīng)答信號(hào)可以不斷讀取內(nèi)存的數(shù)據(jù) 如果不想讀了,告訴E2PROM不想要數(shù)據(jù)了,就發(fā)送一個(gè)“非應(yīng)答位NAK(1)”。發(fā)送結(jié)束信號(hào)(STOP)停止總線
3、連續(xù)讀數(shù)據(jù)  E2PROM支持連續(xù)寫(xiě)操作,操作和單個(gè)字節(jié)類(lèi)似,先發(fā)送設(shè)備寫(xiě)操作地址(DEVICE ADDRESS),然后發(fā)送內(nèi)存起始地址(WORD ADDRESS),MCU會(huì)回應(yīng)一個(gè)應(yīng)答信號(hào)(ACK)后,E2PROM會(huì)繼續(xù)傳輸下一個(gè)地址的數(shù)據(jù),MCU不斷回應(yīng)應(yīng)答信號(hào)可以不斷讀取內(nèi)存的數(shù)據(jù)。E2PROM的地址指針會(huì)自動(dòng)遞增,數(shù)據(jù)會(huì)依次保存在內(nèi)存中。不應(yīng)答發(fā)送結(jié)束信號(hào)后終止傳輸。 //IIC發(fā)送數(shù)據(jù)//address 要寫(xiě)入的地址//date 要寫(xiě)入的數(shù)據(jù)void write_add(uchar address,uchar date){
IIC_Start();
IIC_Send_Byte(0xA0);
delay(2);
IIC_Send_Byte(address);
delay(2);
IIC_Send_Byte(date);
delay(2);
IIC_Stop();}//IIC讀取數(shù)據(jù)// address 要讀取數(shù)據(jù)的地址uchar read_add(uchar address) //指定地址讀一個(gè)字節(jié)數(shù)據(jù){uchar add;IIC_Start();IIC_Send_Byte(0xA0);delay(2);IIC_Send_Byte(address);delay(2);IIC_Start();IIC_Send_Byte(0xA1);delay(2);dd=IIC_Read_Byte();
IIC_Stop();return add;}1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
軟件IIC和硬件IICIIC分為軟件IIC和硬件IIC 軟件IIC:軟件IIC通信指的是用單片機(jī)的兩個(gè)I/O端口模擬出來(lái)的IIC,用軟件控制管腳狀態(tài)以模擬I2C通信波形,軟件模擬寄存器的工作方式。 硬件IIC:一塊硬件電路,硬件I2C對(duì)應(yīng)芯片上的I2C外設(shè),有相應(yīng)I2C驅(qū)動(dòng)電路,其所使用的I2C管腳也是專(zhuān)用的,硬件(固件)I2C是直接調(diào)用內(nèi)部寄存器進(jìn)行配置。 硬件I2C的效率要遠(yuǎn)高于軟件的,而軟件I2C由于不受管腳限制,接口比較靈活。
|