摘要:協議物理層原理總體特征協議層起始和停止條件數據有效性響應應答尋址讀數據寫數據單片機通訊軟件模擬硬件外設一物理層原理總線,分別由串行數據線和串行時鐘線及上拉電阻組成。第八步,主機發送一個校驗碼,此校驗值為步數據產生的校驗碼。
I2C 總線,分別由SDA(串行數據線)和SCL(串行時鐘線)及上拉電阻組成。
通信原理是通過對SCL和SDA線高低電平時序的控制,來 產生I2C總線協議所需要的信號進行數據的傳遞。在總線空閑狀態時,這兩根線一般被上面所接的上拉電阻拉高,保持著高電平。
? 連接到總線的器件輸出級必須是漏極開路或集電極開路才能執行線與的功能。
? I2C 總線上的每一個設備都可以作為主設備或者從設備,而且每一個設備都會對應一個唯一的地址(可以從I2C器件的數據手冊得知),主從設備之間就通過這 個地址來確定與哪個器件進行通信。
? I2C 總線上數據的傳輸速率在標準模式下可達 100kbit/s ,在快速模式下可達 400kbit/s ,在高速模式下可達 3.4Mbit/s ,連接到總線的接口數量只由總線電容是 400pF 的限制決定。
? I2C 總線上的主設備與從設備之間以字節(8位)為單位進行雙向的數據傳輸。
I2C協議規定,總線上數據的傳輸必須以一個起始信號作為開始條件,以一個結束信號作為傳輸的停止條件。
起始和結束信號總是由主設備產生。
SDA線上的數據必須在SCL的高電平時保持穩定。
SDA線的高或低電平狀態只有在 SCL 線的時鐘信號是低電平時才能改變。
發送到 SDA 線上的每個字節必須為 8 位,每次傳輸可以發送的字節數量不受限制 ,每個字節后必須跟一個響應位 ,首先傳輸的是數據的最高位(見下圖MSB )
如果從機要完成一些其他功能后(如中斷)才能接收或發送下一個完整的數據字節 ,可以使時鐘線 SCL 保持低電平迫使主機進入等待狀態 ,當從機準備好接收下一個數據字節時釋放時鐘線 SCL, 數據傳輸繼續。
數據傳輸必須帶響應,相關的響應SCL時鐘脈沖由主機產生,在響應的時鐘脈沖期間,發送器釋放 SDA 線(輸出高阻態使SDA線被上拉電阻拉高)。在響應的時鐘脈沖期間,接收器必須將 SDA 線拉低,使它在這個時鐘脈沖的高電平期間保持穩定的低電平。 必須考慮建立和保持時間。
在起始條件 S 后 ,發送了一個從機地址SLAVE ADDRESS, 這個地址共有 7 位,緊接著的第 8 位是數據方向位[R/W], 0 表示寫,1表示讀。接下來的一個bit是應答位NACK/ACK,當這個幀中前面8bits發送完后,接收端獲得SDA控制權,此時接收設備應該在第9個時鐘脈沖之前回復一個ACK(將SDA拉低)以表示接收正常,如果接收設備沒有將SDA拉低,則說明接收設備可能沒有收到數據(如尋址的設備不存在或設備忙)或無法解析收到的消息,如果是這樣,則由master來決定如何處理(stop或repeated start condition)。
10 位從機地址是由在起始條件 S 或重復起始條件 Sr 后的頭兩個字節組成。
第一個字節的頭 7 位是 11110XX 的組合 ,其中:最后兩位 XX 是 10 位地址的兩個最高位 MSB
第一個字節的第 8 位是 R/ W 位, 決定了報文的方向 :0 表示寫, 1 表示讀。
如果 R/ W 位是 0 則下一個字節是 10 位從機地址剩下的 8 位;
如果 R/ W 位是 1 則下一個字節是從機發送給主機的數據。
仲裁過程
主機只能在總線空閑的時侯啟動傳輸。兩個或多個主機可能在起始條件的最小持續時間內產生一個起始條件,結果在總線上產生一個規定的起始條件。
當 SCL 線是高電平時,仲裁在 SDA 線發生。這樣,在其他主機發送低電平時,發送高電平的主機將退出競爭, 因為總線上的電平與它自己的電平不相同。
仲裁可以持續多位。第一個階段是比較地址位,如果每個主機都嘗試尋址相同的器件,當主機作發送器時仲裁會繼續比較數據位,當主機作接收器時仲裁會繼續比較響應位。
IIC總線的地址和數據信息由贏得仲裁的主機決定,因此在仲裁過程中不會丟失信息。
丟失仲裁的主機可以產生時鐘脈沖,直到丟失仲裁的該字節末尾。
可以看到在起始信號的第3個時鐘周期低電平時,DATA1的SDA輸出高電平,而DATA2向SDA輸出低電平,SDA總線保持低電平,仲裁給到DATA2,即DATA1的主機退出競爭,不再發送數據。DATA1主機贏得仲裁,SDA總線已傳送的數據和DATA1發送的數據保持一致。
7位尋址為例 CPU作為主接收器
第一步,主機發送一個起始信號S。
第二步,主機發送7bit從機地址。此處需要注意,發送數據時,無法發送7bit數據,此處發送了7bit地址+1bit讀寫選擇位,即發送7bit+R/W。最低位為1表示讀,為0表示寫。
第三步,從機產生一個ACK應答信號。
//第四步,主機發送寄存器地址。
//第五步,從機產生一個ACK應答信號。
//第六步,主機再次發送一個起始信號。
//第七步,主機發送7bit從機地址,即7bit+R/W。最低位為1表示讀,為0表示寫。
//第八步,從機產生一個ACK應答信號。
第九步,主機讀取一個字節(8bit)的數據(相當于從機發送一個字節)。
第十步,CPU產生一個ACK應答信號。
//第十一步,讀取一個CRC校驗碼。
第十二步,CPU產生一個NACK無應答信號。
第十三步,主機產生一個停止信號。
常規的使用就是第一、二、三、九、十、十二、十三步。
注釋掉的是單片機集成的硬件IIC配置通信的整個完整的通訊過程。
CPU作為主發送器
第一步,主機發送一個起始信號。
第二步,發送7bit從機地址。此處需要注意,發送數據時,無法發送7bit數據,此處發送了7bit地址+1bit讀寫選擇位,即發送7bit+R/W。最低位為1表示讀,為0表示寫。
第三步,從機產生一個ACK應答信號。
//第四步,主機發送寄存器地址,8bit數據。
//第五步,從機產生一個ACK應答信號。
第六步,主機發送一個字節(8bit)數據。
第七步,從機產生一個ACK應答信號。
//第八步,主機發送一個CRC校驗碼,此CRC校驗值為2、4、6步數據產生的校驗碼。
第九步,從機既可以發送一個應答信號,也可以發送一個無應答信號。
第十步,主機發送一個停止信號。
CPU與EEPROM通訊為例
相關函數:
void I2C_Delay(void); //延時,以防單片機速度太快void I2C_Start(void); //起始信號void I2C_Stop(void); //終止信號u8 I2C_SendByte(u8 data); //寫一個字節u8 I2C_ReadByte(void); //讀一個字節void EEPROM_Write(u8 address, u8 data); //往EEPROM的一個地址寫一個數據u8 EEPROM_Read (u8 address); //讀EEPROM的一個地址的數據
stm32軟件模擬配置流程:
初始化GPIO
void I2c_Init(void); //初始化GPIO
模擬總線SDA, SCL ,GPIO引腳開漏輸出
寫起始信號函數
void I2C_Start(void); //起始信號
SDA, SCL拉高 , 延時
SDA = 1; SCL = 1; delay();
SDA由高變低 , 延時
SDA = 0; delay();
SCL拉低,延時等待發送/接收
SCL = 0; delay();
寫終止信號函數
void I2C_Stop(void); //終止信號
SCL拉低后將SDA拉低 (SCL低電平時SDA可變),延時
SCL = 0; SDA = 0; delay();
SCL拉高 , 延時
SCL = 1; delay();
SDA由低變高 , 延時
SDA = 1; delay();
等待應答信號函數
u8 I2C_WaitToAck(void); //讀取器件ACK應答
產生/不產生ACK應答
void I2C_Ack(void);
void I2C_NoAck(void);
寫一個字節
讀一個字節
//延時static void I2c_Delay(void){ /*CPU主頻72MHz 10: SCL頻率205KHz 7: SCL頻率347KHz,高電平1.5us,低電平2.87us; 5: SCL頻率421KHz,高電平1.25us,低電平2.375us;*/ u8 i; for(i = 0; i < 10; i++);}//起始信號void I2C_Start(void){ I2C_SDA_High(); //SDA=1 I2C_SCL_High(); //SCL=1 I2C_Delay(); I2C_SDA_Low(); I2C_Delay(); I2C_SCL_Low(); I2C_Delay();}//終止信號void I2C_Stop(void){ I2C_SDA_Low(); I2C_SCL_High(); I2C_Delay(); I2C_SDA_High(); I2C_Delay();}//寫一個字節u8 I2C_SendByte(uint8_t Byte){ uint8_t i; /* 先發送高位字節 */ for(i = 0 ; i < 8 ; i++) { if(Byte & 0x80) { I2C_SDA_High(); } else { I2C_SDA_Low(); } I2C_Delay(); I2C_SCL_High(); I2C_Delay(); I2C_SCL_Low(); I2C_Delay(); if(i == 7) { I2C_SDA_High(); /* 釋放SDA總線 */ } Byte <<= 1; /* 左移一位 */ I2C_Delay(); }} //讀取一個字節u8 I2C_ReadByte(void){ uint8_t i; uint8_t value; /* 先讀取最高位即bit7 */ value = 0; for(i = 0 ; i < 8 ; i++) { value <<= 1; I2C_SCL_High(); I2C_Delay(); if(I2C_SDA_READ()) { value++; } I2C_SCL_Low(); I2C_Delay(); } return value;}//產生一個ACK應答信號void I2C_Ack(void){ I2C_SDA_Low(); I2C_Delay(); I2C_SCL_High(); //cpu產生一個時鐘 I2C_Delay(); I2C_SCL_Low(); I2C_Delay(); I2C_SDA_High();}//產生一個非ACK信號void I2C_NoAck(void){ I2C_SDA_High(); I2C_Delay(); I2C_SCL_High(); //cpu產生一個時鐘 I2C_Delay(); I2C_SCL_Low(); I2C_Delay();}//產生時鐘讀取器件ACK應答信號u8 I2C_WaitToAck(void){ u8 redata; I2C_SDA_High(); //CPU釋放SDA總線 I2C_Delay(); I2C_SCL_High(); //SCL=1此時器件會返回ACK應答 I2C_Delay(); if(I2C_SDA_READ()) //CPU讀取SDA口線狀態 { redata = 1; } else { redata = 0; } I2C_SCL_Low(); I2C_Delay(); return redata;}
與EEPROM通訊為例
typedef struct{ uint32_t I2C_ClockSpeed; //設置SCL時鐘頻率 <40,000 uint32_t I2C_Mode; //工作模式 I2C模式或SMBUS模式 uint32_t I2C_DutyCycle; //指定時鐘占空比 低/高=2/1或16/9 uint32_t I2C_OwnAddress1; //指定自身的I2C設備地址 uint32_t I2C_Ack; //使能或關閉響應(一般使能) uint32_t I2C_AcknowledgedAddress; //指定地址長度 7位/10位} I2C_InitTypeDef;
參考:
原理:《IIC總線協議中文版》
代碼實現:博客園
學習:野火、正點原子、普中科技
部分圖片來源于網站,侵刪
修改時間:2021年09月27日
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/121624.html
摘要:如圖所示在了解起始條件和停止條件后,我們再來看看在這個過程中數據的傳輸是如何進行的。四參考資料通過接口實現溫濕度的采集硬件和軟件區別 stm32通過I2C接口實現...
摘要:從設備使能信號,由主設備控制,只有該信號為預先規定的使能信號,對該芯片的操作才有效,這就允許再統一總線上連接多個設備。點對點通信中,接口不需要進行尋址操作,但是沒有指定的流控制,沒有應答機制確認是否接收到數據。 1、GPIO 通用可編程IO接口,對于簡單的外圍設備或者電路,需要CPU為之提供...
摘要:使用庫讀寫環境光照度傳感器本文將教大家如何快速使用庫讀取光照度數據。五實驗樣機測試展示通過之前配置好的面板,通過涂鴉智能進行配網實時采集光照度傳感器的數據。 使用STM32 HAL庫讀寫環境光照度傳感器(BH1750) 本文將教大家如何快速使用STM32HAL庫讀取光照度數據。 實現功能:通...
摘要:問你是否用過什么操作系統,,等,這個是加分項,然后會問一些的協議,進程與線程區別,還有一些電機算法,或者視覺等等。 大家好,我是Q3。我是一名2022屆的一名電氣工程及其自動化的學生,學校是二本就不說啦。 ??我今天主要是來淺談一下我的面試經驗以及一些遇到的問題。 ??首先我來聊一下我的學習...
摘要:帶中文字庫的是一種具有位位并行線或線串行多種接口方式,內部含有國標一級二級簡體中文字庫的點陣圖形液晶顯示模塊其顯示分辨率為。貼片按鍵模塊支持標準的協議,完整的協議棧。以最低成本提供最大實用性,為功能嵌入其他系統提供無限可能。 項目簡介 開發環境: Keil5.14,CubeMX6.0.1,主...
閱讀 2968·2023-04-25 19:45
閱讀 2690·2021-11-19 09:40
閱讀 690·2021-10-14 09:49
閱讀 2667·2021-09-30 09:47
閱讀 2200·2021-09-26 09:55
閱讀 1220·2021-09-22 16:01
閱讀 2808·2019-08-30 14:19
閱讀 705·2019-08-29 16:44