日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

ah20温度采集

發(fā)布時間:2023/12/16 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 ah20温度采集 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

文章目錄

  • 實(shí)驗(yàn)?zāi)康?/li>
  • 實(shí)驗(yàn)材料
    • 軟件
    • 硬件
    • AHT20
  • 實(shí)驗(yàn)原理
    • 什么是I2C
      • 物理層
      • 邏輯層
    • 硬件I2C與軟件I2C
  • 項(xiàng)目制作
    • 制作一個標(biāo)準(zhǔn)庫項(xiàng)目
    • 導(dǎo)入AHT20模塊與USART配置
    • 修改main函數(shù)
  • 實(shí)驗(yàn)現(xiàn)象
  • 總結(jié)
  • 參考資料

實(shí)驗(yàn)?zāi)康?/h1>

學(xué)習(xí)I2C總線通信協(xié)議,使用STM32F103完成基于I2C協(xié)議的AHT20溫濕度傳感器的數(shù)據(jù)采集,并將采集的溫度-濕度值通過串口輸出。

具體任務(wù):

1)解釋什么是“軟件I2C”和“硬件I2C”? (閱讀野火配套教材的第23章“I2C–讀寫EEPROM”原理章節(jié))

2)閱讀AHT20數(shù)據(jù)手冊,編程實(shí)現(xiàn):每隔2秒鐘采集一次溫濕度數(shù)據(jù),并通過串口發(fā)送到上位機(jī)(win10)。

實(shí)驗(yàn)材料

軟件

  • KEIL5
  • FlyMcu
  • FireTools串口助手

硬件

  • STM32F103C8T6最小開發(fā)板
  • AHT20溫濕度傳感器
  • CH340模塊
  • 面包板一塊
  • 杜邦線若干

AHT20

AHT20是奧松電子生產(chǎn)的,一種基于IIC協(xié)議的溫濕度傳感器。單片機(jī)通過給AHT20通過IIC協(xié)議發(fā)送指令,可以從AHT20讀取溫濕度數(shù)據(jù)到單片機(jī)。

我在本實(shí)驗(yàn)中使用的芯片的引腳圖如下:

根據(jù)引腳定義進(jìn)行連接,按規(guī)定編寫代碼給傳感器發(fā)送指令,讀取溫濕度數(shù)據(jù)。

實(shí)驗(yàn)原理

什么是I2C

I2C 通訊協(xié)議(Inter-Integrated Circuit)是由 Phiilps 公司開發(fā)的,由于它引腳少,硬件實(shí)現(xiàn)簡單,可擴(kuò)展性強(qiáng),不需要 USART、CAN 等通訊協(xié)議的外部收發(fā)設(shè)備,現(xiàn)在被廣泛地使用在系統(tǒng)內(nèi)多個集成電路(IC)間的通訊。

I2C可以分成物理層與協(xié)議層。

物理層

I2C是一個支持設(shè)備的總線??蛇B接多個 I2C 通訊設(shè)備,支持多個通訊主機(jī)及多個通訊從機(jī)。對于I2C 總線,只使用兩條總線線路,一條雙向串行數(shù)據(jù)線(SDA) ,一條串行時鐘線(SCL)。

連接到總線上的設(shè)備在輸出時使用開漏輸出的模式。當(dāng)總線上沒有設(shè)備發(fā)數(shù)據(jù)時,大家輸出高阻態(tài),總線被上拉電阻設(shè)置為高電平。當(dāng)有設(shè)備發(fā)送數(shù)據(jù)時,如果發(fā)送1,設(shè)備輸出高阻態(tài),接收設(shè)備與上拉電阻相連得到1;如果輸出0,由于上拉電阻把總線與電源隔開,整條總線被設(shè)置成低電平。

邏輯層

首先主機(jī)向總線發(fā)送開始信號,發(fā)送之后再發(fā)送從機(jī)地址(7位或10位)+讀或?qū)?#xff08;0或1),對應(yīng)的從機(jī)再給主機(jī)發(fā)送確認(rèn)信號。

如果是主機(jī)發(fā)數(shù)據(jù),主機(jī)會發(fā)送8位數(shù)據(jù)到從機(jī),從機(jī)發(fā)送確認(rèn)信號,主機(jī)再接著發(fā)下8位數(shù)據(jù)。發(fā)送完畢后,主機(jī)發(fā)送停止信號,傳輸結(jié)束。

如果是主機(jī)讀數(shù)據(jù),從機(jī)會發(fā)送8位數(shù)據(jù)給主機(jī),主機(jī)收到后發(fā)送確認(rèn)信號,接著收下8位數(shù)據(jù)。主機(jī)可以發(fā)送非確認(rèn)信號停止接收。發(fā)送非停止信號后,主機(jī)再發(fā)送結(jié)束信號。

I2C常使用復(fù)合模式,有兩次起始信號。主機(jī)找到從機(jī)后,再發(fā)送傳感器里面的寄存器地址,再進(jìn)行讀寫。

野火的資料里面有圖片讀寫過程的示意圖:

硬件I2C與軟件I2C

硬件I2C是直接利用 STM32 芯片中的硬件 I2C 外設(shè),在初始化好 I2C 外設(shè)后,只需要把某寄存器位置 1,此時外設(shè)就會控制對應(yīng)的 SCL 及 SDA 線自動產(chǎn)生 I2C 起始信號,不需要內(nèi)核直接控制引腳的電平。

軟件I2C直接使用 CPU 內(nèi)核按照 I2C 協(xié)議的要求控制 GPIO 輸出高低電平,從而模擬I2C。

本實(shí)驗(yàn)中,使用I2C讀寫寄存器的具體實(shí)現(xiàn)已經(jīng)被官方寫成函數(shù)給我們使用,我們僅需要根據(jù)示例代碼,按自己需要進(jìn)行調(diào)用即可。但是想要分析它的源碼,就必須先了解I2C協(xié)議。

項(xiàng)目制作

制作一個標(biāo)準(zhǔn)庫項(xiàng)目

制作標(biāo)準(zhǔn)庫項(xiàng)目過程較為復(fù)雜,野火的資料庫提供了項(xiàng)目模板。我也寫好了一個模板在這個鏈接里面,可以下載好后根據(jù)文本文件里面的提示進(jìn)行構(gòu)建。

導(dǎo)入AHT20模塊與USART配置

構(gòu)建好標(biāo)準(zhǔn)庫項(xiàng)目后,使用空main函數(shù)編譯無誤后,進(jìn)行這一步。

由于本實(shí)驗(yàn)實(shí)現(xiàn)的需求是使用AHT20模塊采集溫濕度數(shù)據(jù),并將采集到的數(shù)據(jù)發(fā)送給上位機(jī)顯示。因此要使用AHT20相關(guān)的代碼以及配置串口。

對于AHT20的代碼,可以下載官方的文檔。點(diǎn)擊這里下載。

注意,下載到的代碼有可能會有bug,下載好代碼后,進(jìn)入.c文件查看Init_I2C_Sensor_Port(void)函數(shù),看SDA對應(yīng)的GPIO口以及是否為開漏輸出。

檢查IIC的GPIO口配置正確后,剪切AHT20-21_DEMO_V1_3.c文件中的示例主函數(shù)到main.c中。

接著進(jìn)行USART配置。具體的配置過程不再贅述,我貼出自己寫好的模塊化代碼,可以分別復(fù)制到頭文件與源文件中導(dǎo)入項(xiàng)目。

我的代碼僅做了對USART1的配置:

//usart.h #ifndef __PSD_USART_H__ #define __PSD_USART_H__ #include "stm32f10x.h" void Usart_1_Config();//usart1初始配置 void Usart_SendByte(USART_TypeDef *pUSARTx, uint8_t ch);//發(fā)送字符 void Usart_SendString(USART_TypeDef *pUSARTx, char *ch);//發(fā)送字符串 void Usart_SendHalfWord(USART_TypeDef *pUSARTx, uint16_t ch);//發(fā)送無符號16位數(shù)據(jù) void Usart_SendWord(USART_TypeDef *pUSARTx, uint32_t ch);//發(fā)送無符號32位數(shù)據(jù) void Usart_SendNum_Uint8(USART_TypeDef *pUSARTx, uint8_t num);//發(fā)送Uint8類型數(shù)字 void Usart_SendNum_Uint16(USART_TypeDef *pUSARTx, uint16_t num);//發(fā)送Uint16類型數(shù)字 void Usart_SendNum_Uint32(USART_TypeDef *pUSARTx, uint32_t num);//發(fā)送Uint32類型數(shù)字 void Usart_SendNum_Int8(USART_TypeDef *pUSARTx, int8_t num);//發(fā)送int8類型數(shù)字 void Usart_SendNum_Int16(USART_TypeDef *pUSARTx, int16_t num);//發(fā)送int16類型數(shù)字 void Usart_SendNum_Int32(USART_TypeDef *pUSARTx, int32_t num);//發(fā)送int32類型數(shù)字 void Usart_SendNum_Double(USART_TypeDef *pUSARTx, double num);//發(fā)送double類型數(shù)字 #endif //usart.c #include "psd_usart.h" #include "math.h" static void NVIC_Configuration(){NVIC_InitTypeDef NVIC_InitStruct;NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1;NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1;NVIC_InitStruct.NVIC_IRQChannel = USART1_IRQn;NVIC_Init(&NVIC_InitStruct); } void Usart_1_Config(){RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//打開串口GPIO時鐘RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);//打開串口時鐘//配置RX,TX的GPIO口GPIO_InitTypeDef GPIO_InitStruct;GPIO_InitStruct.GPIO_Pin = GPIO_Pin_10; //將TX配置為浮空輸入模式GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;GPIO_Init(GPIOA,&GPIO_InitStruct);GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9; //將RX配置為復(fù)用推挽輸出模式GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA,&GPIO_InitStruct);//配置USART1USART_InitTypeDef USART_InitStruct;USART_InitStruct.USART_WordLength = USART_WordLength_8b;USART_InitStruct.USART_StopBits = USART_StopBits_1;USART_InitStruct.USART_BaudRate = 115200;USART_InitStruct.USART_Parity = USART_Parity_No;USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;USART_InitStruct.USART_Mode = USART_Mode_Rx|USART_Mode_Tx;USART_Init(USART1,&USART_InitStruct);USART_Cmd(USART1,ENABLE);NVIC_Configuration();USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); }void Usart_SendByte(USART_TypeDef *pUSARTx, uint8_t ch){USART_SendData(pUSARTx,ch);while(USART_GetFlagStatus(pUSARTx,USART_FLAG_TXE)==RESET); }void Usart_SendString(USART_TypeDef *pUSARTx, char *ch){unsigned int k = 0;do{Usart_SendByte(pUSARTx,*(ch+k));k++;}while(*(ch+k)!='\0');while(USART_GetFlagStatus(pUSARTx,USART_FLAG_TXE)==RESET); }void Usart_SendHalfWord(USART_TypeDef *pUSARTx, uint16_t ch){uint8_t temp_h, temp_l;temp_h = (ch&0xFF00)>>8;temp_l = ch&0xff;Usart_SendByte(pUSARTx, temp_h);Usart_SendByte(pUSARTx, temp_l);}void Usart_SendWord(USART_TypeDef *pUSARTx, uint32_t ch){uint8_t temp_h, temp_l;temp_h = (ch&0xFFFF0000)>>16;temp_l = ch&0xffff;Usart_SendHalfWord(pUSARTx, temp_h);Usart_SendHalfWord(pUSARTx, temp_l);}void Usart_SendNum_Uint8(USART_TypeDef *pUSARTx, uint8_t num){if (num == 0){Usart_SendByte(pUSARTx,'0');return;}char dat[4];dat[3] = '\0';uint8_t i = 0;while(num>0){uint8_t n = num%10;if(n==0) dat[2-i] = '0';else if(n==1) dat[2-i] = '1';else if(n==2) dat[2-i] = '2';else if(n==3) dat[2-i] = '3';else if(n==4) dat[2-i] = '4';else if(n==5) dat[2-i] = '5';else if(n==6) dat[2-i] = '6';else if(n==7) dat[2-i] = '7';else if(n==8) dat[2-i] = '8';else if(n==9) dat[2-i] = '9';i++;num/=10;}uint8_t a = 3-i;Usart_SendString(pUSARTx,&dat[a]); } void Usart_SendNum_Uint16(USART_TypeDef *pUSARTx, uint16_t num){if (num == 0){Usart_SendByte(pUSARTx,'0');return;}char dat[6];dat[5] = '\0';uint8_t i = 0;while(num>0){uint8_t n = num%10;if(n==0) dat[4-i] = '0';else if(n==1) dat[4-i] = '1';else if(n==2) dat[4-i] = '2';else if(n==3) dat[4-i] = '3';else if(n==4) dat[4-i] = '4';else if(n==5) dat[4-i] = '5';else if(n==6) dat[4-i] = '6';else if(n==7) dat[4-i] = '7';else if(n==8) dat[4-i] = '8';else if(n==9) dat[4-i] = '9';i++;num/=10;}uint8_t a = 5-i;Usart_SendString(pUSARTx,&dat[a]); } void Usart_SendNum_Uint32(USART_TypeDef *pUSARTx, uint32_t num){if (num == 0){Usart_SendByte(pUSARTx,'0');return;}char dat[11];dat[10] = '\0';uint8_t i = 0;while(num>0){uint8_t n = num%10;if(n==0) dat[9-i] = '0';else if(n==1) dat[9-i] = '1';else if(n==2) dat[9-i] = '2';else if(n==3) dat[9-i] = '3';else if(n==4) dat[9-i] = '4';else if(n==5) dat[9-i] = '5';else if(n==6) dat[9-i] = '6';else if(n==7) dat[9-i] = '7';else if(n==8) dat[9-i] = '8';else if(n==9) dat[9-i] = '9';i++;num/=10;}uint8_t a = 10-i;Usart_SendString(pUSARTx,&dat[a]); } void Usart_SendNum_Double(USART_TypeDef *pUSARTx, double num){int32_t num1 = floor(num);int32_t num2 = floor((num-num1)*1000);Usart_SendNum_Int32(pUSARTx,num1);Usart_SendByte(pUSARTx,'.');Usart_SendNum_Int32(pUSARTx,num2); } void Usart_SendNum_Int8(USART_TypeDef *pUSARTx, int8_t num){if(num>=0) Usart_SendNum_Uint8(pUSARTx,num);else{if(num == -128){Usart_SendString(pUSARTx,"-128");}else{num = 0 - num;Usart_SendByte(pUSARTx,'-');Usart_SendNum_Uint8(pUSARTx,num);}} } void Usart_SendNum_Int16(USART_TypeDef *pUSARTx, int16_t num){if(num>=0) Usart_SendNum_Uint16(pUSARTx,num);else{if(num == -32768){Usart_SendString(pUSARTx,"-32768");}else{num = 0 - num;Usart_SendByte(pUSARTx,'-');Usart_SendNum_Uint16(pUSARTx,num);}} } void Usart_SendNum_Int32(USART_TypeDef *pUSARTx, int32_t num){if(num>=0) Usart_SendNum_Uint32(pUSARTx,num);else{if(num == -2147483648){Usart_SendString(pUSARTx,"-2147483648");}else{num = 0 - num;Usart_SendByte(pUSARTx,'-');Usart_SendNum_Uint32(pUSARTx,num);}} }

修改main函數(shù)

官方的實(shí)例代碼已經(jīng)讀出了放大10倍的溫濕度數(shù)據(jù),在main.c函數(shù)中找到對應(yīng)的位置,在讀到的數(shù)據(jù)后面使用串口通信代碼,將溫濕度除以10之后將數(shù)據(jù)發(fā)送給串口助手。

代碼如下:

int32_t main(void) {Usart_1_Config();//配置Usart1uint32_t CT_data[2];volatile int c1,t1;/***********************************************************************************//**///上電初始化SDA,SCL的IO口/***********************************************************************************/Init_I2C_Sensor_Port();/***********************************************************************************//**///①剛上電,產(chǎn)品芯片內(nèi)部就緒需要時間,延時100~500ms,建議500ms/***********************************************************************************/Delay_1ms(500);/***********************************************************************************//**///②上電第一次發(fā)0x71讀取狀態(tài)字,判斷狀態(tài)字是否為0x18,如果不是0x18,進(jìn)行寄存器初始化/***********************************************************************************/if((AHT20_Read_Status()&0x18)!=0x18){AHT20_Start_Init(); //重新初始化寄存器Delay_1ms(10);}/***********************************************************************************//**///③根據(jù)客戶自己需求發(fā)測量命令讀取溫濕度數(shù)據(jù),當(dāng)前while(1)循環(huán)發(fā)測量命令讀取溫濕度數(shù)據(jù),僅供參考/***********************************************************************************/while(1){AHT20_Read_CTdata_crc(CT_data);if(CT_data[0]==0xff&&CT_data[1]==0xff){Usart_SendString(USART1,"CRC檢驗(yàn)未通過!");}else{c1 = CT_data[0]*100*10/1024/1024; //計(jì)算得到濕度值c1(放大了10倍)t1 = CT_data[1]*200*10/1024/1024-500;//計(jì)算得到溫度值t1(放大了10倍)//下一步客戶處理顯示數(shù)據(jù),Usart_SendString(USART1,"溫度:");Usart_SendNum_Double(USART1,t1/10.0,1);Usart_SendByte(USART1,'\n');Usart_SendString(USART1,"濕度:");Usart_SendNum_Double(USART1,c1/10.0,1);Usart_SendByte(USART1,'\n');Usart_SendString(USART1,"數(shù)據(jù)通過檢驗(yàn)!\n");Usart_SendByte(USART1,'\n');}Delay_1ms(2000);}}

實(shí)驗(yàn)現(xiàn)象

查看SDA,SCL對應(yīng)的GPIO口,將AHT20芯片的VCC,SDA,GND,SCL四個引腳與芯片對應(yīng)的引腳在面包板上連接好,連接好硬件后燒錄程序到芯片中,打開串口助手,發(fā)現(xiàn)接收到溫度與濕度數(shù)據(jù)。

根據(jù)上圖的函數(shù)查看自己下的代碼使用的哪個GPIO口。

總結(jié)

本實(shí)驗(yàn)實(shí)現(xiàn)了使用AHT20傳感器收集溫濕度數(shù)據(jù),并發(fā)送到串口助手。涉及到I2C與Usart配置。為了完成這個實(shí)驗(yàn),我將Usart模塊化,制作了輸出中文,浮點(diǎn)數(shù),數(shù)字的函數(shù),鞏固了之前所學(xué)習(xí)的知識。此外還通過AHT20的官方例子學(xué)習(xí)了I2C的應(yīng)用。

參考資料

  • https://blog.csdn.net/qq_43279579/article/details/111597278

  • 《零死角玩轉(zhuǎn)STM32——F103指南者》

  • 《AHT20產(chǎn)品手冊》

總結(jié)

以上是生活随笔為你收集整理的ah20温度采集的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 亚洲资源站 | 玖玖玖视频 | 骚虎av| 日本高清不卡在线 | 成人先锋av | 色哟哟国产精品 | 可以直接看的毛片 | 福利网站在线 | 日韩不卡高清 | 欧美顶级少妇做爰 | 在线观看国产一级片 | 国产精品国产精品国产专区不片 | 免费视频一二三区 | 国产情侣av自拍 | 免费v片在线观看 | 中文字幕激情小说 | 好吊妞精品视频 | 午夜影院在线观看视频 | 日本欧美在线播放 | 一级少妇毛片 | 国产欧美日韩视频在线观看 | 精品人妻av一区二区 | 国产三级精品三级 | 中文字幕日本一区 | 一区二区三区四区人妻 | 少妇av一区二区三区 | 亚洲乱码国产乱码精品精剪 | 一边吃奶一边摸做爽视频 | 欧美高清不卡 | 亚洲一区精品视频 | 国产精品视频网站 | 毛片无遮挡高清免费观看 | 毛片在哪里看 | 中文成人在线 | 香蕉黄视频 | 91大神小宝寻花在线观看 | 亚洲激情图片区 | 无码人妻精品一区二区三区99v | 欧美,日韩,国产精品免费观看 | 欧美又粗又大xxxxbbbb疯狂 | av黄色在线播放 | 在线观看色网站 | 91刺激视频| 中文字幕免费高清网站 | 秘密基地免费观看完整版中文 | 亚洲久久天堂 | 久草一本 | 麻豆国产一区二区三区 | 啪视频在线 | 黄色一级毛片 | 久久亚洲AV无码精品 | 亚洲永久免费网站 | 都市激情国产精品 | 67194少妇在线观看 | 福利小视频 | 亚洲美女屁股眼交8 | 亚洲av无码一区二区乱子伦 | 四虎影视成人永久免费观看亚洲欧美 | 秋霞影院一区二区 | 天天爽天天爽天天爽 | 精品无码成人久久久久久免费 | 91热爆在线| 精品中文字幕av | 免费看欧美成人a片无码 | 日韩深夜福利 | 樱桃视频污污 | 欧美丰满老熟妇xxxxx性 | 黑人玩弄人妻一区二区三区免费看 | 91精品国产91久久久久 | 色97色| 男女插插插视频 | 秋霞黄色网 | 免费色av | 男女午夜影院 | 岛国大片在线免费观看 | 亚洲精品中文字幕乱码无线 | 久久久久久九九九 | 你懂的成人| 嫩模一区二区三区 | 人妻少妇久久中文字幕 | 色老妹 | 欧美成人精品欧美一级 | 色欲亚洲Av无码精品天堂 | 欧美黄色一区二区 | 国产av一区精品 | 欧美一区二区高清视频 | 男人天堂2020 | 亚洲精品一卡二卡 | 男同激情视频 | 激情伊人五月天 | 我和我的太阳泰剧在线观看泰剧 | 蜜臀中文字幕 | 顶级尤物极品女神福利视频 | 亚洲の无码国产の无码步美 | 91视频黄版 | 久色精品视频 | 99re这里只有精品在线 | 欧美黑人又粗又大的性格特点 | 久久小视频 |