本程序對應的開發板爲藍橋杯嵌入式開發板stm32f103rbt6,爲中型mcu。DHT11是單線接口數字溫溼度傳感器,溫度測量範圍是0~50℃,溼度測量範圍是20%~90%RH,溫度測量精度是±2℃,溼度測量精度是±5%RH。
DHT11包含一個電阻式感溼元件和一個NTC(負溫度係數)測溫元件,通過雙向單線輸出溫溼度數據,一次數據輸出爲40位(高位在前,大約需要4ms),數據格式爲:
8位溼度整數+8位溼度小數+8位溫度整數+8位溫度小數+8位校驗和。其中校驗和是前4個8位數據之和的後8位
讀取步驟
連接:
P4.7(PA7)-P3.7(HDQ)
dht11.c
#include "stm32f10x.h"
#define delay_us(X) delay(X*72/5)
void delay(unsigned int n)
{
while (n--);
}
void dht11_init (void )
{
GPIO_InitTypeDef GPIO_InitStructure;
/* Enable clock */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA , ENABLE);
/* Configure Ports */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_SetBits(GPIOA, GPIO_Pin_7);
}
void mode_input(void )
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
}
void mode_output(void )
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
}
unsigned int dht11_read(void)
{
int i;
long long val;
int timeout;
GPIO_ResetBits(GPIOA, GPIO_Pin_7);
delay_us(18000); //pulldown for 18ms
GPIO_SetBits(GPIOA, GPIO_Pin_7);
delay_us( 20 ); //pullup for 30us
mode_input();
//等待DHT11拉高,80us
timeout = 5000;
while( (! GPIO_ReadInputDataBit (GPIOA, GPIO_Pin_7)) && (timeout > 0) ) timeout--; //wait HIGH
//等待DHT11拉低,80us
timeout = 5000;
while( GPIO_ReadInputDataBit (GPIOA, GPIO_Pin_7) && (timeout > 0) ) timeout-- ; //wait LOW
#define CHECK_TIME 28
for(i=0;i<40;i++)
{
timeout = 5000;
while( (! GPIO_ReadInputDataBit (GPIOA, GPIO_Pin_7)) && (timeout > 0) ) timeout--; //wait HIGH
delay_us(CHECK_TIME);
if ( GPIO_ReadInputDataBit (GPIOA, GPIO_Pin_7) )
{
val=(val<<1)+1;
} else {
val<<=1;
}
timeout = 5000;
while( GPIO_ReadInputDataBit (GPIOA, GPIO_Pin_7) && (timeout > 0) ) timeout-- ; //wait LOW
}
mode_output();
GPIO_SetBits(GPIOA, GPIO_Pin_7);
if (((val>>32)+(val>>24)+(val>>16)+(val>>8) -val ) & 0xff ) return 0;
else return val>>8;
}
dht11.h
#ifndef __DHT11_H
#define __DHT11_H
void dht11_init (void );
void delay(unsigned int n);
unsigned int dht11_read(void);
#endif
主程序
#include "stm32f10x.h"
#include "lcd.h"
#include "dht11.h"
u32 TimingDelay = 0;
void Delay_Ms(u32 nTime);
unsigned int Dht_Val;
unsigned char string[20],Sec1,Sec;
unsigned long Tick_Ms;
void Dht11_Proc(void);
int main(void)
{
STM3210B_LCD_Init();
LCD_Clear(Blue);
LCD_SetBackColor(Blue);
LCD_SetTextColor(White);
SysTick_Config(SystemCoreClock/1000);
dht11_init();
LCD_DisplayStringLine(Line0," ");
LCD_DisplayStringLine(Line1," ");
LCD_DisplayStringLine(Line2," ");
LCD_DisplayStringLine(Line3," ");
LCD_DisplayStringLine(Line4," ");
LCD_DisplayStringLine(Line5," ");
LCD_DisplayStringLine(Line6," ");
LCD_DisplayStringLine(Line7," ");
LCD_DisplayStringLine(Line8," ");
LCD_DisplayStringLine(Line9," ");
while (1)
{
Dht11_Proc();
}
}
void Dht11_Proc(void)
{
if(Sec1!=Sec)
{
Sec1=Sec;
Dht_Val=dht11_read();
sprintf((char*)string,"Humidity: %2d%",Dht_Val>>24);
LCD_DisplayStringLine(Line1,string);
sprintf((char*)string,"Temperature: %2dC",(Dht_Val>>8)&0xff);
LCD_DisplayStringLine(Line4,string);
}
}
void Delay_Ms(u32 nTime)
{
TimingDelay = nTime;
while(TimingDelay != 0);
}
void SysTick_Handler(void)
{
TimingDelay--;
Tick_Ms++;
if(Tick_Ms%1000==0)Sec++;
}