天天看點

IIC總線從零梳理(結合STM32平台)

時間:2017/06/07 22:01 IIC總線的EEPROM G15電裝.王維鋆 常用的串行總線協定: 常用的微機與外設之間進行資料傳輸的串行總線主要有 I2C總線、SPI總線和SCI總線 。 其中I2C總線以 同步串行2線方式進行通信 (一條時鐘線,一條資料線)。 SPI總線則以 同步串行3線方式進行通信 (一條時鐘線,一條資料輸入線,一條資料輸出線)。 SCI總線是以 異步方式進行通信 (一條資料輸入線,一條資料輸出線)。 1-wire,即單線總線,又叫單總線。例如DS18B20溫度傳感器就是用的這種總線結構. 我們這裡重點詳解下I2C串行總線,我們這裡以資料手冊的IIC時序圖為例講起,看不懂時序圖的小夥伴必須補上來了. 一.I2C串行總線的組成及工作原理. 1. I2C總線是PHLIPS公司推出的一種串行總線,它隻有兩根雙向信号線。一根是資料線SDA(serial data I/O),另一根是時鐘線SCL(serial clock)。 2. 如下圖所示,IIC總線上可以挂多個器件,而每個器件都有唯一的位址,這樣可以辨別通信目标。資料的通信的方式采用主從方式,主機負責主動聯系從機,而從機則被動回應資料。

IIC總線從零梳理(結合STM32平台)
IIC總線從零梳理(結合STM32平台)
IIC總線從零梳理(結合STM32平台)

二.I2C總線傳輸協定 1. 資料位的有效性規定: SCL為高電平期間,資料線上的資料必須保持穩定,隻有SCL信号為低電平期間,SDA狀态才允許變化。如圖所示

IIC總線從零梳理(結合STM32平台)
IIC總線從零梳理(結合STM32平台)

2. I2C的起始和終止信号 SCL線為高電平期間,SDA線由高電平向低電平的變化表示起始信号;SCL線為高電平期間,SDA線由低電平向高電平的變化表示終止信号。如圖所示

IIC總線從零梳理(結合STM32平台)
IIC總線從零梳理(結合STM32平台)

3. I2C位元組的傳送與應答 每一個位元組必須保證是8位長度。資料傳送時,先傳送最高位(MSB),每一個被傳送的位元組後面都必須跟随一位應答位(即一幀共有9位).如圖所示

IIC總線從零梳理(結合STM32平台)
IIC總線從零梳理(結合STM32平台)

4. 應答位的作用 主機在發送資料時,每次發送一位元組資料,都需要讀取從機應答位,當從機空閑可以接收該位元組資料時,從機會發出應答(一幀資料的第9位為“0”),當從機正忙于其他工作的處理來不及接收主機發送的資料時,從機會發出非應答(一幀資料的第9位為“1”)主機則應發出終止信号以結束資料的繼續傳送,主機通過從機發出的應答位來判斷從機是否成功接收資料.

當主機接收資料時,它收到最後一個資料位元組後,必須向從機發出一個結束傳送的信号。這個信号是由對從機的“非應答”來實作的。然後,從機釋放SDA線,以允許主機産生終止信号。 貼個IIC總線在傳送資料過程中信号 時序圖.好好研究好時序圖,一切都可以輕松解決.

IIC總線從零梳理(結合STM32平台)
IIC總線從零梳理(結合STM32平台)

三.IIC驅動代碼了解(以51為例,模拟IIC) 這裡,我用51單片機為例寫下IIC 驅動代碼,實作包括 IIC 的初始化( IO 口)、 IIC 開始、 IIC 結束、 ACK、 IIC 讀寫等功能.IIC驅動代碼是根據時序圖來編寫的,結合着時序圖看,感興趣的小夥伴可以試着自己寫一下底層驅動代碼.由于是根據時序圖來編寫的,就沒什麼要說明的 I2C起始信号程式: void I2C_Start() { SCL = 1; _nop_(); //51的一個機器周期 1.08506us SDA = 1; delay_5us(); SDA = 0; delay_5us(); } I2C終止信号程式: void I2C_Stop() { SDA = 0; _nop_(); SCL = 1; delay_5us(); SDA = 1; delay_5us(); } I2C主機檢測從機應答: bit Test_ACK() { SCL = 1; //在時鐘總線為高電平期間可以讀取應答信号 delay_5us(); if (SDA) { SCL = 0; I2C_Stop(); return(0); } else { SCL = 0; return(1); } } I2C主機發送應答: void Master_ACK(bit i) { SCL = 0; _nop_(); if (i) { SDA = 0; } else { SDA = 1; } _nop_(); SCL = 1;//資料保持穩定 _nop_(); SCL = 0; _nop_(); SDA = 1; _nop_(); } 根據這些IIC驅動代碼編寫自己的讀寫函數就可以和外部IIC器件通信了. 四.EEPROM—— AT24CXX梳理 1.I2C寫資料流程

IIC總線從零梳理(結合STM32平台)

在起始信号後必須傳送一個從機的位址(7位)我們開發闆上的AT24C02器件位址為0xa0,第8位是資料的傳送方向位(R/T),用“0”表示主機發送資料(T),“1”表示主機接收資料(R)

IIC總線從零梳理(結合STM32平台)

2.I2C讀資料流程

IIC總線從零梳理(結合STM32平台)
IIC總線從零梳理(結合STM32平台)

在讀資料時也要先發送器件位址,讀寫方向為寫,因為我們下一幀需要發送從AT24C02内那個單元開始讀,之後需在發一次器件位址這個時候讀寫方向就為讀了,接着我們就可以從總線上讀取資料

對IIC晶片外設的初始化,這裡就不講解了,很簡單的配置過程。 初始化好I2C後,就可以使用I2C通訊了,我這裡還是以51為例,配合火哥的模拟IIC通訊曆程看,你會發現,發送資料流程和接收資料流程原理是一樣的。 3. 下面放圖 火哥的模拟IIC的寫資料曆程 bit I2C_TransmitData(uchar ADDR, DAT) { I2C_Start(); //I2C總線起始 I2C_send_byte(AT24C02_ADDR+0); //發送AT24C02位址加讀寫方向位0(寫) if (!Test_ACK()) //檢測是否發送成功(應答) { return(0); } I2C_send_byte(ADDR); //發送控制位元組ADDR位址輸出使能 if (!Test_ACK()) //檢測是否發送成功(應答) { return(0); } I2C_send_byte(DAT); //發送數字量交由AT24C02轉為模拟量AOUT腳輸出 if (!Test_ACK()) //檢測是否發送成功(應答) { return(0); } I2C_Stop(); //I2C停止信号 return(1); }

IIC總線從零梳理(結合STM32平台)
IIC總線從零梳理(結合STM32平台)

火哥的曆程已經詳細的說明了寫資料的流程,這裡,我就不多此一舉了. 4. uchar I2C_ReceiveData(uchar ADDR) { uchar DAT; I2C_Start(); I2C_send_byte(AT24C02_ADDR+0); if (!Test_ACK()) { return(0); } I2C_send_byte(ADDR); //發送控制位元組位址 Master_ACK(0); //發送非應答 I2C_Start(); //重發起始信号 I2C_send_byte(AT24C02_ADDR+1); //改變讀寫方向(讀) if (!Test_ACK()) { return(0); } DAT = I2C_read_byte(); //把讀取的值賦給形參 Master_ACK(0); //主機發送非應答 I2C_Stop(); //I2C停止信号 return(DAT); //成功傳回1 }

IIC總線從零梳理(結合STM32平台)
IIC總線從零梳理(結合STM32平台)

通過上面的分析,IIC寫資料,讀資料的原理我就講的這麼多了,這是我自己的了解,僅供參考.

繼續閱讀