目 錄
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 實驗效果圖
打開眾想科技多功能監控軟件,接著打開串口,我們在接收區可以觀察到實測采集到周圍環境的溫濕度數據,周圍環境的溫度大約 攝氏度左右、濕度是 左右,說明我們溫濕度模塊工作正常,程序編寫和設計思路吻合。 |