本文作者: 陽光,e小白網(wǎng)址:www.e-xiaobai.com 在剛開始接觸單片機的時候,會被板級內(nèi)的各種通訊接口方式弄的暈頭轉(zhuǎn)向。嵌入式系統(tǒng)中常用板級通訊方式有:并口(8位、16位)、SPI(4線、3線)、IIC、USB、TYPE-C等。具體采用什么通訊方式,要根據(jù)實際項目情況選擇。并口傳輸速度快,處理數(shù)據(jù)量大,像處理圖形圖像優(yōu)先考慮,硬件成本高;串口傳輸速度相對比較慢,接線簡單,硬件成本低。這里詳細介紹下IIC通訊方式的使用。 一、IIC 簡介 IIC(Inter-Integrated Circuit)總線是由NXP(原PHILIPS)公司開發(fā)的兩線式串行總線,用于連接單片機及其外圍設(shè)備。多用于主控制器和從器件間的主從通信,適用數(shù)據(jù)量少,傳輸距離短場合。在 MCU 與被控 IC 之間、IC 與 IC 之間進行二線制、雙向、同步半雙工傳輸。IIC傳輸速度分為標準100Kbps、快速400Kbps、高速3.4Mbps,目前大多數(shù)器件都支持快速傳輸。IIC總線的傳輸距離受到布線、速度、總線電容的影響,雖然沒有明確規(guī)定距離,但是建議不要超過300mm,否則最好加上IIC中繼芯片。 二、IIC物理層接線 從上圖可以看出,在IIC物理層有主機(MCU)、從機(IIC器件);2條總線,SCL(時鐘線)和SDA(數(shù)據(jù)線)及上拉電阻(必接4.7K-10K)。 所有接到I2C總線設(shè)備上的串行數(shù)據(jù)SDA都必須接到總線的SDA上,各設(shè)備的時鐘線SCL接到總線的SCL上。I2C總線上的每個設(shè)備都自己一個唯一的地址,來確保不同設(shè)備之間訪問的準確性。器件的物理地址是器件廠商出廠設(shè)定好的,須按照IC手冊設(shè)定。 在IIC總線中可以接多個主機,其中任何一個能夠進行發(fā)送和接收的設(shè)備都可以成為主總線。一個主機能夠控制信號的傳輸和時鐘頻率。當然,在任何時間點上只能有一個主機控制。 --------------------------------------------------------------------------------------------------------------- 三、IIC協(xié)議層 IIC 總線在傳送數(shù)據(jù)過程中共有三種類型信號, 它們分別是:啟始信號(Start)、終止信號(Stop)和應(yīng)答信號(Ack)。 啟始信號:SCL 為高電平時(1),SDA 由高電平向低電平跳變,表示起始信號,接下來可以進行數(shù)據(jù)傳輸,必須有; 終止信號:SCL 為高電平時(1),SDA 由低電平向高電平跳變,表示終止信號,表示結(jié)束數(shù)據(jù)傳輸,必須有; 應(yīng)答信號:接收端器件(不論主從)在接收到 8bit 數(shù)據(jù)后,向發(fā)送端器件(不論主從)發(fā)出特定的低電平脈沖,表示已收到數(shù)據(jù)。發(fā)送端向接收端發(fā)出一個信號后,等待接收端發(fā)出一個應(yīng)答信號,發(fā)送端接收到應(yīng)答信號后,根據(jù)實際情況作出是否繼續(xù)傳遞數(shù)據(jù)的判斷。若在約定的等待周期內(nèi)未收到應(yīng)答信號,判斷為接收端接收數(shù)據(jù)不成功。 非應(yīng)答信號:若接收端希望結(jié)束數(shù)據(jù)傳輸,則可以向發(fā)送端發(fā)一個“非應(yīng)答信號NAck”,接收端收到此信號后會產(chǎn)生一個終止信號,結(jié)束傳輸。 IIC 總線時序圖 啟始信號:SCL高電平(1)狀態(tài)下,SDA由高(1)變低(0),保持至少4.7us后,產(chǎn)生啟始信號;程序表示如下 void IIC_Start() { SDA=1; //確保SDA線為高電平 SCL=1; //確保SCL高電平 delay_us(5); //保持5us SDA=0; //在SCL為高時拉低SDA,產(chǎn)生啟始信號 delay_us(5); } 終止信號:SCL高電平(1)狀態(tài)下,SDA由高(0)變低(1),保持至少4.7us后,產(chǎn)生終止信號;程序表示如下 void IIC_Stop() { SDA=0; //確保SDA線為低電平 SCL=1; //確保SCL高電平 delay_us(5); SDA=1; //在SCL為高時拉高SDA線,產(chǎn)生終止信號 delay_us(5); } 應(yīng)答信號:主機SCL拉高,讀取從機SDA的電平,為低電平(SDA=0)表示產(chǎn)生應(yīng)答,為有效應(yīng)答位(ACK,簡稱應(yīng)答位),表示接收器已經(jīng)成功地接收了該字節(jié),可以繼續(xù)發(fā)送;若為高電平(SDA=1)時,為非應(yīng)答位(NACK),一般表示接收器接收該字節(jié)沒有成功,結(jié)束發(fā)送。如下圖 每發(fā)送一個字節(jié)(8個bit)后,在一個字節(jié)傳輸?shù)?個時鐘后的第九個時鐘期間,接收器接收數(shù)據(jù)后必須回一個ACK應(yīng)答信號給發(fā)送器,這樣才能進行數(shù)據(jù)傳輸。程序表示如下: //主機產(chǎn)生應(yīng)答信號Ack void IIC_Ack(void) { SCL=0; //先拉低SCL,使得SDA數(shù)據(jù)可以發(fā)生改變 SDA=0; //SAD=0,產(chǎn)生應(yīng)答信號 delay_us(2); SCL=1; delay_us(5); SCL=0; //一個SCL時鐘等待周期 delay_us(5); SDA=1; //釋放SDA總線控制權(quán) } 有時候從機因某種原因不需要對主機應(yīng)答時,須將SDA置為高電平(1),由主機產(chǎn)生終止信號結(jié)束數(shù)據(jù)傳輸。程序表示如下: //主機產(chǎn)生非應(yīng)答信號NAck void IIC_NAck(void) { SCL=0; //先拉低SCL,使得SDA數(shù)據(jù)可以發(fā)生改變 SDA=1; //SAD=1,產(chǎn)生非應(yīng)答信號 delay_us(2); SCL=1; delay_us(5); SCL=0; delay_us(5); } 在實際寫程序時,我們可以用一個等待應(yīng)答子程序來判斷應(yīng)答信號,程序如下: 等待接收端的應(yīng)答信號:應(yīng)答0,非應(yīng)答1 u8 IIC_WaitAck (void) { u8 temptime; //臨時計時器 SDA=1; // 釋放SDA線的控制權(quán) SCL=1; delay_us(5); if(SDA_READ==1) // 如果讀回的SDA=1,則為非應(yīng)答 { temptime++; if(temp>250) //超時,這里250大概數(shù)參考 { IIC_Stop(); //停止傳輸 return 1; } } SCL=0; // SCL拉低 delay_us(5); return 0; //如果讀回的SDA=0,則為應(yīng)答 }
|