一、I2C總線通信協(xié)議原理
1、I2C協(xié)議簡介
I2C 通訊協(xié)議(Inter-Integrated Circuit)是由Phiilps公司開發(fā)的,由于它引腳少,硬件實現(xiàn)簡單,可擴展性強,不需要USART、CAN等通訊協(xié)議的外部收發(fā)設(shè)備,現(xiàn)在被廣泛地使用在系統(tǒng)內(nèi)多個集成電路(IC)間的通訊。
STM32標準庫則是在寄存器與用戶代碼之間的軟件層。對于通訊協(xié)議,我們也以分層的方式來理解,最基本的是把它分為物理層和協(xié)議層。物理層規(guī)定通訊系統(tǒng)中具有機械、電子功能部分的特性,確保原始數(shù)據(jù)在物理媒體的傳輸。協(xié)議層主要規(guī)定通訊邏輯,統(tǒng)一收發(fā)雙方的數(shù)據(jù)打包、解包標準。簡單來說物理層規(guī)定我們用嘴巴還是用肢體來交流,協(xié)議層則規(guī)定我們用中文還是英文來交流。
2、 I2C物理層
I2C通訊設(shè)備之間的常用連接方式
它的物理層有如下特點
:
(1) 它是一個支持設(shè)備的總線?!翱偩€”指多個設(shè)備共用的信號線。在一個I2C通訊總線中,可連接多個I2C通訊設(shè)備,支持多個通訊主機及多個通訊從機。
(2) 一個I2C總線只使用兩條總線線路,一條雙向串行數(shù)據(jù)線(SDA) ,一條串行時鐘線 (SCL)。數(shù)據(jù)線即用來表示數(shù)據(jù),時鐘線用于數(shù)據(jù)收發(fā)同步。
(3) 每個連接到總線的設(shè)備都有一個獨立的地址,主機可以利用這個地址進行不同設(shè)備之間的訪問。
(4) 總線通過上拉電阻接到電源。當(dāng)I2C設(shè)備空閑時,會輸出高阻態(tài),而當(dāng)所有設(shè)備都空閑,都輸出高阻態(tài)時,由上拉電阻把總線拉成高電平。
(5) 多個主機同時使用總線時,為了防止數(shù)據(jù)沖突,會利用仲裁方式?jīng)Q定由哪個設(shè)備占用總線。
(6) 具有三種傳輸模式:標準模式傳輸速率為100kbit/s ,快速模式為400kbit/s ,高速模式下可達 3.4Mbit/s,但目前大多I2C設(shè)備尚不支持高速模式。
(7) 連接到相同總線的 IC 數(shù)量受到總線的最大電容 400pF 限制
3、協(xié)議層
(1)基本讀寫過程
主機寫數(shù)據(jù)到從機
主機由從機中讀數(shù)據(jù)
I2C通訊復(fù)合格式
數(shù)據(jù)由主機傳輸至從機S
: 傳輸開始信號 SLAVE_ADDRESS: 從機地址
數(shù)據(jù)由從機傳輸至主機R/W
——: 傳輸方向選擇位,1為讀,0為寫A/A
—— : 應(yīng)答(ACK)或非應(yīng)答(NACK)信號
P : 停止傳輸信號
I2C的協(xié)議定義了通訊的起始和停止信號、數(shù)據(jù)有效性、響應(yīng)、仲裁、時鐘同步和地址廣播等環(huán)節(jié)。
其中S表示由主機的I2C接口產(chǎn)生的傳輸起始信號(S),這時連接到I2C總線上的所有從機都會接收到這個信號。 起始信號產(chǎn)生后,所有從機就開始等待主機緊接下來廣播 的從機地址信號 (SLAVE_ADDRESS)。在I2C總線上,每個設(shè)備的地址都是唯一的,當(dāng)主機廣播的地址與某個設(shè)備地址相同時,這個設(shè)備就被選中了,沒被選中的設(shè)備將會忽略之后的數(shù)據(jù)信號。根據(jù)I2C協(xié)議,這個從機地址可以是7位或10位。 在地址位之后,是傳輸方向的選擇位,該位為0時,表示后面的數(shù)據(jù)傳輸方向是由主機傳輸至從機,即主機向從機寫數(shù)據(jù)。該位為1時,則相反,即主機由從機讀數(shù)據(jù)。 從機接收到匹配的地址后,主機或從機會返回一個應(yīng)答(ACK)或非應(yīng)答(NACK)信號,只有接收到應(yīng)答信號后,主機才能繼續(xù)發(fā)送或接收數(shù)據(jù)。寫數(shù)據(jù)
若配置的方向傳輸位為“寫數(shù)據(jù)”方向,即第一幅圖的情況,廣播完地址,接收到應(yīng)答信號后,主機開始正式向從機傳輸數(shù)據(jù)(DATA),數(shù)據(jù)包的大小為8位,主機每發(fā)送完一個字節(jié)數(shù)據(jù),都要等待從機的應(yīng)答信號(ACK),重復(fù)這個過程,可以向從機傳輸N個數(shù)據(jù),這個N沒有大小限制。當(dāng)數(shù)據(jù)傳輸結(jié)束時,主機向從機發(fā)送一個停止傳輸信號§,表示不再傳輸數(shù)據(jù)。讀數(shù)據(jù)
若配置的方向傳輸位為“讀數(shù)據(jù)”方向,即第二幅圖的情況,廣播完地址,接收到應(yīng)答信號后,從機開始向主機返回數(shù)據(jù)(DATA),數(shù)據(jù)包大小也為8位,從機每發(fā)送完一個數(shù)據(jù),都會等待主機的應(yīng)答信號(ACK),重復(fù)這個過程,可以返回N個數(shù)據(jù),這個N也沒有大小限制。當(dāng)主機希望停止接收數(shù)據(jù)時,就向從機返回一個非應(yīng)答信號(NACK),則從機自動停止數(shù)據(jù)傳輸。讀和寫數(shù)據(jù)
除了基本的讀寫,I2C通訊更常用的是復(fù)合格式,即第三幅圖的情況,該傳輸過程有兩次起始信號(S)。一般在第一次傳輸中,主機通過 SLAVE_ADDRESS尋找到從設(shè)備后,發(fā)送一段“數(shù)據(jù)”,這段數(shù)據(jù)通常用于表示從設(shè)備內(nèi)部的寄存器或存儲器地址(注意區(qū)分它與SLAVE_ADDRESS的區(qū)別);在第二次的傳輸中,對該地址的內(nèi)容進行讀或?qū)?。也就是說,第一次通訊是告訴從機讀寫地址,第二次則是讀寫的實際內(nèi)容。
(2)通訊的起始和停止信號
前文中提到的起始(S)和停止§信號是兩種特殊的狀態(tài),見圖起始信號與停止信號
。當(dāng) SCL 線是高電平時 SDA 線從高電平向低電平切換,這個情況表示通訊的起始。當(dāng) SCL 是高電平時 SDA 線由低電平向高電平切換,表示通訊的停止。起始和停止信號一般由主機產(chǎn)生。
(3) 數(shù)據(jù)有效性
I2C使用SDA信號線來傳輸數(shù)據(jù),使用SCL信號線進行數(shù)據(jù)同步。見圖數(shù)據(jù)有效性
。SDA數(shù)據(jù)線在SCL的每個時鐘周期傳輸一位數(shù)據(jù)。傳輸時,SCL為高電平的時候SDA表示的數(shù)據(jù)有效,即此時的SDA為高電平時表示數(shù)據(jù)“1”,為低電平時表示數(shù)據(jù)“0”。當(dāng)SCL為低電平時,SDA的數(shù)據(jù)無效,一般在這個時候SDA進行電平切換,為下一次表示數(shù)據(jù)做好準備。
(4)地址及數(shù)據(jù)方向
I2C總線上的每個設(shè)備都有自己的獨立地址,主機發(fā)起通訊時,通過SDA信號線發(fā)送設(shè)備地址(SLAVE_ADDRESS)來查找從機。I2C協(xié)議規(guī)定設(shè)備地址可以是7位或10位,實際中7位的地址應(yīng)用比較廣泛。緊跟設(shè)備地址的一個數(shù)據(jù)位用來表示數(shù)據(jù)傳輸方向,它是數(shù)據(jù)方向位(R/W——),第8位或第11位。數(shù)據(jù)方向位為“1”時表示主機由從機讀數(shù)據(jù),該位為“0”時表示主機向從機寫數(shù)據(jù)。如圖設(shè)備地址(7位)及數(shù)據(jù)傳輸方向
讀數(shù)據(jù)方向時,主機會釋放對SDA信號線的控制,由從機控制SDA信號線,主機接收信號,寫數(shù)據(jù)方向時,SDA由主機控制,從機接收信號。
(5)響應(yīng)
I2C的數(shù)據(jù)和地址傳輸都帶響應(yīng)。響應(yīng)包括“應(yīng)答(ACK)”和“非應(yīng)答(NACK)”兩種信號。作為數(shù)據(jù)接收端時,當(dāng)設(shè)備(無論主從機)接收到I2C傳輸?shù)囊粋€字節(jié)數(shù)據(jù)或地址后,若希望對方繼續(xù)發(fā)送數(shù)據(jù),則需要向?qū)Ψ桨l(fā)送“應(yīng)答(ACK)”信號,發(fā)送方會繼續(xù)發(fā)送下一個數(shù)據(jù);若接收端希望結(jié)束數(shù)據(jù)傳輸,則向?qū)Ψ桨l(fā)送“非應(yīng)答(NACK)”信號,發(fā)送方接收到該信號后會產(chǎn)生一個停止信號,結(jié)束信號傳輸。 圖響應(yīng)與非響應(yīng)信號
傳輸時主機產(chǎn)生時鐘,在第9個時鐘時,數(shù)據(jù)發(fā)送端會釋放SDA的控制權(quán),由數(shù)據(jù)接收端控制SDA,若SDA為高電平,表示非應(yīng)答信號(NACK),低電平表示應(yīng)答信號(ACK)。
4、軟件I2C
由于直接控制GPIO引腳電平產(chǎn)生通訊時序時,需要由CPU控制每個時刻的引腳狀態(tài),所以稱之為“軟件模擬協(xié)議”方式。
5、硬件I2C
STM32的I2C片上外設(shè)專門負責(zé)實現(xiàn)I2C通訊協(xié)議,只要配置好該外設(shè),它就會自動根據(jù)協(xié)議要求產(chǎn)生通訊信號,收發(fā)數(shù)據(jù)并緩存起來,CPU只要檢測該外設(shè)的狀態(tài)和訪問數(shù)據(jù)寄存器,就能完成數(shù)據(jù)收發(fā)。
二、STM32基于I2C協(xié)議的溫濕度傳感器的數(shù)據(jù)采集
每隔2秒鐘采集一次溫濕度數(shù)據(jù),并通過串口發(fā)送到上位機。
了解AHT20芯片的相關(guān)信息,具體信息請到官方下載對應(yīng)產(chǎn)品介紹文檔
資料鏈接:http://www.aosong.com/class-36.html
1、代碼撰寫
(1)AHT20芯片的使用過程 read_AHT20_once
函數(shù)
void read_AHT20_once(void)
{
delay_ms(10);
reset_AHT20();//重置AHT20芯片
delay_ms(10);
init_AHT20();//初始化AHT20芯片
delay_ms(10);
startMeasure_AHT20();//開始測試AHT20芯片
delay_ms(80);
read_AHT20();//讀取AHT20采集的到的數(shù)據(jù)
delay_ms(5);
}
(2)AHT20芯片讀取數(shù)據(jù) read_AHT20
函數(shù)
void read_AHT20(void)
{
uint8_t i;
for(i=0; i<6; i++)
{
readByte[i]=0;
}
I2C_Start();//I2C啟動
I2C_WriteByte(0x71);//I2C寫數(shù)據(jù)
ack_status = Receive_ACK();//收到的應(yīng)答信息
readByte[0]= I2C_ReadByte();//I2C讀取數(shù)據(jù)
Send_ACK();//發(fā)送應(yīng)答信息
readByte[1]= I2C_ReadByte();
Send_ACK();
readByte[2]= I2C_ReadByte();
Send_ACK();
readByte[3]= I2C_ReadByte();
Send_ACK();
readByte[4]= I2C_ReadByte();
Send_ACK();
readByte[5]= I2C_ReadByte();
SendNot_Ack();
//Send_ACK();
I2C_Stop();//I2C停止函數(shù)
//判斷讀取到的第一個字節(jié)是不是0x08,0x08是該芯片讀取流程中規(guī)定的,如果讀取過程沒有問題,就對讀到的數(shù)據(jù)進行相應(yīng)的處理
if( (readByte[0] & 0x68) == 0x08 )
{
H1 = readByte[1];
H1 = (H1<<8) | readByte[2];
H1 = (H1<<8) | readByte[3];
H1 = H1>>4;
H1 = (H1*1000)/1024/1024;
T1 = readByte[3];
T1 = T1 & 0x0000000F;
T1 = (T1<<8) | readByte[4];
T1 = (T1<<8) | readByte[5];
T1 = (T1*2000)/1024/1024 - 500;
AHT20_OutData[0] = (H1>>8) & 0x000000FF;
AHT20_OutData[1] = H1 & 0x000000FF;
AHT20_OutData[2] = (T1>>8) & 0x000000FF;
AHT20_OutData[3] = T1 & 0x000000FF;
}
else
{
AHT20_OutData[0] = 0xFF;
AHT20_OutData[1] = 0xFF;
AHT20_OutData[2] = 0xFF;
AHT20_OutData[3] = 0xFF;
printf("讀取失?。。?!");
}
printf("\r\n");
//根據(jù)AHT20芯片中,溫度和濕度的計算公式,得到最終的結(jié)果,通過串口顯示
printf("溫度:%d%d.%d",T1/100,(T1/10)%10,T1%10);
printf("濕度:%d%d.%d",H1/100,(H1/10)%10,H1%10);
printf("\r\n");
}
編譯調(diào)試成功無誤燒錄即可。
完整代碼鏈接
https://pan.baidu.com/s/1z1SybDqb_6V9veqxqLs7sQ
提取碼:o72s
2、電路連接
1-----GND | 3V3 |
---|---|
2----SDA | PB7 |
3----GND | GND |
4----SCL | PB6 |
3、結(jié)果展示
總結(jié)
本次實驗主要問題是有個文件路徑不正確,無法編譯,可以直接把該文件刪除,直接將以前的驅(qū)動文件添加到本工程中。即可燒錄運行。
通過本次實驗了解到了I2C總線協(xié)議,以及AHT20溫濕度傳感器的使用。文章來源:http://www.zghlxwxcb.cn/news/detail-430417.html
參考
https://blog.csdn.net/qq_46467126/article/details/121436790?spm=1001.2014.3001.5502
https://blog.csdn.net/as480133937/article/details/105366932
https://blog.csdn.net/u010632165/article/details/109188507文章來源地址http://www.zghlxwxcb.cn/news/detail-430417.html
到了這里,關(guān)于STM32溫度濕度采集(AHT20)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!