在物聯倉儲系統和智能小車中,很多情況下都需要使用I2C總線協議進行數據傳輸,本文將對該協議做一個簡單的整理介紹。
一、I2C 總線的一些特征:
• 只要求兩條總線線路一條串行數據線SDA 一條串行時鐘線SCL
• 每個連接到總線的器件都可以通過唯一的地址和一直存在的簡單的主機從機關系軟件設定地址主機可以作為主機發送器或主機接收器
• 它是一個真正的多主機總線如果兩個或更多主機同時初始化數據傳輸可以通過沖突檢測和仲裁防止數據被破壞
• 串行的8 位雙向數據傳輸位速率在標準模式下可達100kbit/s 快速模式下可達400kbit/s 高速模式下可達3.4Mbit/s
• 片上的濾波器可以濾去總線數據線上的毛刺波保證數據完整
• 連接到相同總線的IC 數量只受到總線的大電容400pF 限制
二、I2C總線在傳送數據過程中共有三種類型信號:開始信號、結束信號和應答信號。
開始信號:SCL為高電平時,SDA由高電平向低電平跳變,開始傳送數據。
結束信號:SCL為高電平時,SDA由低電平向高電平跳變,結束傳送數據。
應答信號:接收數據的IC在接收到8bit數據后,向發送數據的IC發出特定的低電平脈沖,表示已收到數據。程序如下所示:
起始和結束:
bool I2C_Start(void)
{
SDA_H;
SCL_H;
I2C_delay();
if(!SDA_read)return FALSE; // SDA線為低電平則總線忙,退出
SDA_L; // 拉低SDA線(當SCL為高電平時,SDA由高電平向低電平跳變表示開始信號)
I2C_delay();
if(SDA_read) return FALSE; // SDA線為高電平則總線出錯,退出
SDA_L; //數據為準備好時,拉低SCL線
I2C_delay();
return TRUE;
}
發出開始信號之后,設備在數據未準備好時,拉低SCL線,這樣主設備可知從設備未發送數據,從設備在數據準備好,可以發送的時候,停止拉低SCL線,這時候才開始真正的數據傳輸。程序如下所示:
void I2C_Stop(void)
{
SCL_L;
I2C_delay();
SDA_L;
I2C_delay();
SCL_H; // SCL為高電平時,SDA由低電平向高電平跳變,結束傳送數據
I2C_delay();
SDA_H;
I2C_delay();
}
STOP在單主環境下非必要,但在多主環境就非常必要,主控總線的設備發送STOP后,通知總線其他設備總線已經閑置。
void I2C_Ack(void)
{
SCL_L;
I2C_delay();
SDA_L;
I2C_delay();
SCL_H;
I2C_delay();
SCL_L;
I2C_delay();
}
當主機作為接收設備時,主機對后一個字節不應答,以向發送設備(從設備)標識數據傳送結束。這是因為每次傳輸都應得到應答信號后再進行下一個字節傳送。如果此時接收機應答了,那它就接收的不是后一個字節了。如果是后一個字節,第9個時鐘周期發送的是非應答信號(此時發送的不是應答信號就是非應答信號),后發送停止信號。
1)主發從收:主START->主發地址->從ACK->(主發數據->從ACK(循環))->主STOP或主 START啟動下一次傳輸,這一過程中,主控SCL線,從只在ACK時控SDA線,其他時刻主控SDA線。
2)主收從發:主START->從發地址->主ACK->(從發數據->主ACK(循環))->接受至后一個字節時,主 NACK->主 STOP 或主START啟動下一次傳輸。注意,并非每傳輸8位數據之后,都會有ACK信號,有以下3中例外
(1)當從機不能響應從機地址時(例如它正忙于其他事而無法響應IIC總線的操作,或者這個地址沒有對應的從機),在第9個SCL周期內SDA線沒有拉低,即沒有ACK信號。這時,主機發出一個P信號終止傳輸或者重新發出一個S信號開始新的傳輸。
(2)如果從機接收器在傳輸過程中不能接收更多的數據時,它不會發出ACK信號。這樣,主機就可以意識到這點,從而發出一個P信號終止傳輸或者重新發出一個S信號開始新的傳輸。
(3)主機接收器在接收到后一個字節后,也不會發出ACK信號。于是,從機發送器釋放SDA線,以允許主機發出P信號結束傳輸。
位傳輸:
主機向從機發送一字節數據
void I2C_SendByte(u8 SendByte) //數據從高位到低位
{
u8 i=8;
while(i--)
{
SCL_L;
I2C_delay();
if(SendByte&0x80)
SDA_H;
else
SDA_L;
SendByte<<=1;
I2C_delay();
SCL_H;
I2C_delay();
}
SCL_L;
}
三、7位尋址
在起始條件S 后發送了一個從機地址,這個地址共有7 位,緊接著的第8 位是數據方向位R/W ,0表示發送寫、1表示請求數據讀:
數據傳輸一般由主機產生的停止位P終止,但是如果主機仍希望在總線上通訊它可以產生重復起始條件Sr和尋址另一個從機,而不是首先產生一個停止條件。
那么在完整的數據傳輸過程中,stm32如何建立與EEPROM的通訊
1、 配置I/O端口,確定并配置I2C的模式,使能GPIO和I2C時鐘。
2、 寫:
檢測SDA是否空閑;
->按I2C協議發出起始訊號;
->發出7位器件地址和寫模式;
->要寫入的存儲區首地址;
->用頁寫入方式或字節寫入方式寫入數據;
3、 讀:
檢測SDA是否空閑;
->按I2C協議發出起始訊號;
->發出7位器件地址和寫模式(偽寫);
->發出要讀取的存儲區首地址;
->重發起始訊號;
->發出7位器件地址和讀模式;
->接收數據;