STM32 模組篇-溫溼度感測器模組(DHT11)實驗

teavamc發表於2017-06-21
目     錄

5.03.1 概述3

5.03.1.1 效能描述4

5.03.1.2 感測器時序4

5.03.2 實驗目的6

5.03.3 硬體設計7

5.03.4 軟體設計7

5.03.4.1 軟體設計說明8

5.03.4.2 STM32庫函式檔案8

5.03.4.3 自定義標頭檔案8

5.03.4.4 pbdata.h檔案裡的內容是9

5.03.4.5 pbdata.c檔案裡的內容是9

5.03.5  STM32系統時鐘配置SystemInit()12

5.03.6  GPIO引腳時鐘使能12

5.03.7  GPIO管腳電平控制函式12

5.03.8  stm32f10x_it.c檔案裡的內容是13

5.03.9  dht11.h檔案裡的內容是13

5.03.10  dht11.c檔案裡的內容是14

5.03.11  main.c檔案裡的內容是17

5.03.12 程式下載19

5.03.13 實驗效果圖20

 

5.03 溫溼度感測器模組實驗

5.03.1 概述

DHT11 數字溫溼度感測器是一款含有已校準數字訊號輸出的溫溼度複合感測器。它應用專用的數字模組採集技術和溫溼度感測技術,確保產品具有極高的可靠性與卓越的長期穩定性。感測器包括一個電阻式感溼元件和一個NTC測溫元件,並與一個高效能8 位微控制器相連線。因此該產品具有品質卓越、超快響應、抗干擾能力強、價效比極高等優點。每個DHT11 感測器都在極為精確的溼度校驗室中進行校準。校準係數以程式的形式儲存在OTP 記憶體中,感測器內部在檢測訊號的處理過程中要呼叫這些校準係數。單線制序列介面,使系統整合變得簡易快捷。超小的體積、極低的功耗,訊號傳輸距離可達20 米以上,使其成為各類應用甚至最為苛刻的應用場合的最佳選則。

 


DHT11 數字溫溼度感測器模組為4 針PH2.0 封裝。連線方便。如右圖所示。

5.03.1.1 效能描述

1. 供電電壓:3-5.5V

2. 供電電流:最大2.5mA

3. 溫度範圍:0-50℃ 誤差±2℃

4. 溼度範圍:20-90%RH 誤差±5%RH

5. 響應時間: 1/e(63%) 6-30s

6. 測量解析度分別為 8bit(溫度)、8bit(溼度)

7. 取樣週期間隔不得低於1 秒鐘

8. 模組尺寸:30x20mm 

 


註釋:建議連線線長度短於20米時使用5K上拉電阻,大於20米時根據實際情況使用合適的上拉電阻。

5.03.1.2 感測器時序

DATA 用於微處理器與 DHT11之間的通訊和同步,採用單匯流排資料格式,一次通訊時間4ms左右,資料分小數部分和整數部分,具體格式在下面說明,當前小數部分用於以後擴充套件,現讀出為零.操作流程如下:

一次完整的資料傳輸為40bit,高位先出。

資料格式:

8bit溼度整數資料+8bit溼度小數資料

+8bi溫度整數資料+8bit溫度小數資料

+8bit校驗和

資料傳送正確時校驗和資料等於“8bit溼度整數資料+8bit溼度小數資料+8bi溫度整數資料+8bit溫度小數資料”所得結果的末8位。

使用者MCU傳送一次開始訊號後,DHT11從低功耗模式轉換到高速模式,等待主機開始訊號結束後,DHT11傳送響應訊號,送出40bit的資料,並觸發一次訊號採集,使用者可選擇讀取部分資料.從模式下,DHT11接收到開始訊號觸發一次溫溼度採集,如果沒有接收到主機傳送開始訊號,DHT11不會主動進行溫溼度採集.採集資料後轉換到低速模式。

通訊過程如圖

 

 


    匯流排空閒狀態為高電平,主機把匯流排拉低等待DHT11響應,主機把匯流排拉低必須大於18毫秒,保證DHT11能檢測到起始訊號。DHT11接收到主機的開始訊號後,等待主機開始訊號結束,然後傳送80us低電平響應訊號.主機傳送開始訊號結束後,延時等待20-40us後, 讀取DHT11的響應訊號,主機傳送開始訊號後,可以切換到輸入模式,或者輸出高電平均可, 匯流排由上拉電阻拉高。

 


    匯流排為低電平,說明DHT11傳送響應訊號,DHT11傳送響應訊號後,再把匯流排拉高80us,準備傳送資料,每一bit資料都以50us低電平時隙開始,高電平的長短定了資料位是0還是1.格式見下面圖示.如果讀取響應訊號為高電平,則DHT11沒有響應,請檢查線路是否連線正常.當最後一bit資料傳送完畢後,DHT11拉低匯流排50us,隨後匯流排由上拉電阻拉高進入空閒狀態。 

5.03.2 實驗目的

1. 掌握溫度採集模組DHT11的工作原理; 

2. 掌握微控制器實現溫度採集模組DHT11資料採集的基本方法,其中包括硬體和軟體實現兩部分;     

3. 熟悉微控制器資料採集系統中,溫度採集模組DHT11作為感測器物件的系統設計方法。

5.03.3 硬體設計

選用大黃蜂實驗板,溫度採集模組DHT11是成品模組,直接插接到實驗板上即可。硬體設計見“圖5.03.5  溫度採集模組DHT11連線圖”。

 



5.03.4 軟體設計

5.03.4.1 軟體設計說明

    溫度採集模組DHT11是成品模組,直接插接到實驗板上即可。按照上一章介紹的工作原理,我們就可以按照工作時序編寫出資料採集程式。我們還是採用庫函式的方式進行程式設計。

在這節程式設計中,用到了外部中斷函式;prinif 重定向列印輸出函式; USART串列埠通訊函式;定時器函式。

5.03.4.2 STM32庫函式檔案

?

   本節實驗及以後的實驗我們都是用到庫檔案,其中 stm32f10x_gpio.h標頭檔案包含了GPIO埠的定義。stm32f10x_rcc.h 標頭檔案包含了系統時鐘配置函式以及相關的外設時鐘使能函式,所以我們要把這兩個標頭檔案對應的stm32f10x_gpio.c和stm32f10x_rcc.c加到工程中;Misc.c庫函式主要包含了中斷優先順序的設定,stm32f10x_exti.c 庫函式主要包含了外部中斷設定引數,tm32f10x_tim.c庫函式主要包含定時器設定,tm32f10x_usart.c庫函式主要包含序列通訊設定,這些函式也要新增到函式庫中。以上庫檔案包含了本次實驗所有要用到的函式使用功能。

5.03.4.3 自定義標頭檔案

                                        

    我們在每個工程設計中都要建立了兩個公共的檔案,這兩個檔案主要存放我們自定義的公共函式和全域性變數,以方便以後每個功能模組(函式)之間傳遞引數。

5.03.4.4 pbdata.h檔案裡的內容是

   

           

語句 #ifndef、#endif是為了防止pbdata.h檔案被多個檔案呼叫時出現錯誤提示。如果不加這兩條語句,當兩個檔案同時呼叫pbdata檔案時,會提示重複呼叫錯誤。 

5.03.4.5 pbdata.c檔案裡的內容是

下面是pbdata.c檔案詳細內容,在檔案開始還是引用“pbdata.h”檔案。


 5.03.5  STM32系統時鐘配置SystemInit()

在每個工程中必須在開始時配置並啟動STM32系統時鐘,這是基礎,這次也不例外。

5.03.6  GPIO引腳時鐘使能


5.03.7  GPIO管腳電平控制函式

    在主程式中採用while(1)迴圈語句,採用查詢方式不停的讀取溫溼度資料,然後直接通過串列埠送列印輸出到螢幕。

  while(1)
   {
  DHT11_Read_Data(&wd,&sd);//讀取溫溼度值    
  printf("當前環境溫度: %d ℃\r\n",wd);    
  printf("當前環境溼度: %d %%\r\n",sd);    
  delay_ms(1000);
  delay_ms(1000);
   }

 

5.03.8  stm32f10x_it.c檔案裡的內容是

在中斷處理stm32f10x_it.c檔案裡中僅串列埠1子函式非空,進入中斷處理函式後,只有串列埠1有引數輸出。

#include "stm32f10x_it.h" 
#include "stm32f10x_exti.h"
#include "stm32f10x_rcc.h"
#include "misc.h"
#include "pbdata.h"
 
void NMI_Handler(void)
{
}
 
void USART1_IRQHandler(void)
{
   if(USART_GetITStatus(USART1,USART_IT_RXNE)!=RESET)
   {
USART_SendData(USART1,USART_ReceiveData(USART1));
while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);
   }
}
 


5.03.9  dht11.h檔案裡的內容是

函式dht11.h在這裡是為符合溫溼度模組功能自定義的專用功能函式,dht11.h的內容如下:

#ifndef __DHT11_H
#define __DHT11_H 
#include "pbdata.h"
 
#define IO_DHT11 GPIO_Pin_4 //引入中間變數,方便移植
#define GPIO_DHT11 GPIOE //引入中間變數,方便移植
 
#define DHT11_DQ_High GPIO_SetBits(GPIO_DHT11,IO_DHT11) 
#define DHT11_DQ_Low  GPIO_ResetBits(GPIO_DHT11,IO_DHT11)
 
void DHT11_IO_OUT(void);//溫溼度模組輸出函式
void DHT11_IO_IN(void); //溫溼度模組輸入函式
void DHT11_Init(void);  //初始化DHT11
u8   DHT11_Read_Data(u8 *temp,u8 *humi);//讀取溫溼度
u8   DHT11_Read_Byte(void);             //讀出一個位元組
u8   DHT11_Read_Bit(void);              //讀出一個位
u8   DHT11_Check(void);                 //檢測是否存在DHT11
void DHT11_Rst(void);                   //復位DHT11    
#endif
 

5.03.10  dht11.c檔案裡的內容是

 

自定義函式dht11.c的內容如下:

#include "pbdata.h"
 
void DHT11_IO_IN(void)//溫溼度模組輸入函式
{
GPIO_InitTypeDef GPIO_InitStructure;
 
GPIO_InitStructure.GPIO_Pin=IO_DHT11;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIO_DHT11,&GPIO_InitStructure);
}
 
void DHT11_IO_OUT(void)//溫溼度模組輸出函式
{
GPIO_InitTypeDef GPIO_InitStructure;
 
GPIO_InitStructure.GPIO_Pin=IO_DHT11;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
GPIO_Init(GPIO_DHT11,&GPIO_InitStructure);
}
 
//復位DHT11
void DHT11_Rst(void)   
{                 
   DHT11_IO_OUT(); //SET OUTPUT
    DHT11_DQ_Low; //DQ=0
    delay_ms(20);    //拉低至少18ms
    DHT11_DQ_High; //DQ=1 
 delay_us(30);     //主機拉高20~40us
}
 
//等待DHT11的迴應
//返回1:未檢測到DHT11的存在
//返回0:存在
u8 DHT11_Check(void)    
{   
u8 retry=0;//定義臨時變數
DHT11_IO_IN();//SET INPUT 
    while ((GPIO_ReadInputDataBit(GPIO_DHT11,IO_DHT11)==1)&&retry<100)//DHT11會拉低40~80us
{
retry++;
delay_us(1);
}; 
if(retry>=100)return 1;
else retry=0;
    while ((GPIO_ReadInputDataBit(GPIO_DHT11,IO_DHT11)==0)&&retry<100)//DHT11拉低後會再次拉高40~80us
{
retry++;
delay_us(1);
};
if(retry>=100)return 1;    
return 0;
}
//從DHT11讀取一個位
//返回值:1/0
u8 DHT11_Read_Bit(void)  
{
 u8 retry=0;
while((GPIO_ReadInputDataBit(GPIO_DHT11,IO_DHT11)==1)&&retry<100)//等待變為低電平
{
retry++;
delay_us(1);
}
retry=0;
while((GPIO_ReadInputDataBit(GPIO_DHT11,IO_DHT11)==0)&&retry<100)//等待變高電平
{
retry++;
delay_us(1);
}
delay_us(40);//等待40us
if(GPIO_ReadInputDataBit(GPIO_DHT11,IO_DHT11)==1)
return 1;
else 
return 0;   
}
//從DHT11讀取一個位元組
//返回值:讀到的資料
u8 DHT11_Read_Byte(void)    
{        
    u8 i,dat;
    dat=0;
for (i=0;i<8;i++) 
{
   dat<<=1; 
    dat|=DHT11_Read_Bit();
    }    
    return dat;
}
 
//從DHT11讀取一次資料
//temp:溫度值(範圍:0~50°)
//humi:溼度值(範圍:20%~90%)
//返回值:0,正常;1,讀取失敗
u8 DHT11_Read_Data(u8 *temp,u8 *humi)    
{        
 u8 buf[5];
u8 i;
DHT11_Rst();
if(DHT11_Check()==0)
{
for(i=0;i<5;i++)//讀取40位資料
{
buf[i]=DHT11_Read_Byte();
}
if((buf[0]+buf[1]+buf[2]+buf[3])==buf[4])
{
*humi=buf[0];
*temp=buf[2];
}
}else return 1;
return 0;    
}
//初始化DHT11的IO口 DQ 同時檢測DHT11的存在
//返回1:不存在
//返回0:存在     
void DHT11_Init(void)
{     
DHT11_Rst();  //復位DHT11
DHT11_Check();//等待DHT11的迴應
}
 
5.03.11  main.c檔案裡的內容是
#include "pbdata.h"
 
void RCC_Configuration(void);
void GPIO_Configuration(void);
void NVIC_Configuration(void);
void USART_Configuration(void);
 
int fputc(int ch,FILE *f)
{
USART_SendData(USART1,(u8)ch);
while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);
return ch;
}
 
int main(void)
{
   u8 wd=0;      
   u8 sd=0;
 
   RCC_Configuration();//系統時鐘初始化
   GPIO_Configuration();//埠初始化
   USART_Configuration();
   NVIC_Configuration();
 
   DHT11_Init();
   
   while(1)
   {
  DHT11_Read_Data(&wd,&sd);//讀取溫溼度值    
  printf("當前環境溫度: %d ℃\r\n",wd);    
  printf("當前環境溼度: %d %%\r\n",sd);    
  delay_ms(1000);
  delay_ms(1000);
   }
}
 
void RCC_Configuration(void)
{
    SystemInit();//72m
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
}
 
void GPIO_Configuration(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9;//TX
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;
GPIO_Init(GPIOA,&GPIO_InitStructure);
 
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_10;//RX
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA,&GPIO_InitStructure);
}
 
void NVIC_Configuration(void)
{
   NVIC_InitTypeDef NVIC_InitStructure; 
 
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); 
 
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; 
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; 
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; 
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; 
NVIC_Init(&NVIC_InitStructure);
}
 
void USART_Configuration(void)
{
    USART_InitTypeDef  USART_InitStructure;
 
USART_InitStructure.USART_BaudRate=9600;
USART_InitStructure.USART_WordLength=USART_WordLength_8b;
USART_InitStructure.USART_StopBits=USART_StopBits_1;
USART_InitStructure.USART_Parity=USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl=USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode=USART_Mode_Rx|USART_Mode_Tx;
 
USART_Init(USART1,&USART_InitStructure);
USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);
USART_Cmd(USART1,ENABLE);
USART_ClearFlag(USART1,USART_FLAG_TC);
}



5.03.12 程式下載

在這一章節中要掌握DHT11溫溼度感測器工作時序,瞭解常用的溫溼度感測器功能和原理。

請根據下圖所指向的7個重點區域配置。其中(1)號區域根據自己機器的實際情況選擇,我的機器虛擬出來的串列埠號是COM3。(2)號區域請自己選擇程式程式碼所在的資料夾。(7)號區域當程式下載完後,進度條會到達最右邊,並且提示一切正常。(4、5、6)號區域一定要按照上圖顯示的設定。當都設定好以後就可以直接點選(3)號區域的開始程式設計按鈕下傳程式了。

 

本節實驗的原始碼在光碟中:(LY-STM32 光碟資料\1.課程\2,外設篇\模組篇 03.溫溼度感測器模組(DHT11)\程式)

5.03.13 實驗效果圖

開啟眾想科技多功能監控軟體,接著開啟串列埠,我們在接收區可以觀察到實測採集到周圍環境的溫溼度資料,周圍環境的溫度大約     攝氏度左右、溼度是   左右,說明我們溫溼度模組工作正常,程式編寫和設計思路吻合。

相關文章