嵌入式设计与开发项目-DHT11温湿度传感器程序设计
- 一、实现功能
- 二、根据功能实现代码
-
- 1、主文件main.c
- 2、DHT11温湿度的头文件“dht11.h”
- 3、DHT11温湿度源文件dht11.c”
- 三、实现功能过程的注意力和学习点
-
- 1、注意点
- 2.学习知识点

时序学习流程: ①单线空闲时间为高电平,MCU读取数据时,首先发送开始信号(输出低电平,持续时间必须大于18ms),然后切换到输入模式(单线从上拉电阻拉到高电平)等待DHT11; ②DHT11检测到开始信号后,触发数据采集,输出响应信号(低电平,持续时间80us)
一、实现功能
二、根据功能实现代码
1、主文件main.c
#include"key.h" #include"led.h" #include"lcd.h" #include"stdio.h" #include"dht11.h" unsigned int uiDht_Val; unsigned char ucSec,ucSec1; unsigned char pucStr[21]; unsigned long ulTick_ms; void DHT_Proc(void); int main(void) {
SysTick_Config(72000); //定时1ms(HCLK = 72MHz) KEY_Init(); LED_Init(); STM3210B_LCD_Init(); LCD_Clear(Blue); LCD_SetBackColor(Blue);
LCD_SetTextColor(White);
while(1)
{
LED_Disp(ucSec);
DHT_Proc();
}
}
void DHT_Proc(void)
{
if(ucSec != ucSec1)
{
ucSec1 = ucSec;
uiDht_Val = dht11_read();
sprintf((char *)pucStr," Humidity: %2d%%",uiDht_Val >> 24);
LCD_DisplayStringLine(Line3,pucStr);
sprintf((char *)pucStr," Temperature: %dC",(uiDht_Val >> 8)&0xff);
LCD_DisplayStringLine(Line5,pucStr);
}
}
//SysTick 中断处理程序
void SysTick_Handler(void)
{
ulTick_ms++;
if(ulTick_ms % 1000 ==0)
ucSec++;
}
主函数分析:❤️ ❤️ ❤️
- ,已经把DHT11的低八位校验和阉割掉,所以是采集到的数据右移24位;
- 是采集到的数据uiDht_Val右移8位取低八位数据;
2、DHT11温湿度的头文件“dht11.h”
#ifndef __DHT11_H
#define __DHT11_H
void dht11_init (void );
void delay(unsigned int n);
unsigned int dht11_read(void);
void DisplayDht11(void);
#endif
简要分析:❤️ ❤️
- DHT11对于的引脚进行;
- 设定延时函数根据进行接收函数;
- 获取温湿度数据,返回一个;
3、DHT11温湿度的源文件“dht11.c”
#include "stm32f10x.h"
#define delay_us(X) delayd(X*72/5)
void delayd(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 LOW
//等待DHT11拉高,80us
timeout = 5000;
while( GPIO_ReadInputDataBit (GPIOA, GPIO_Pin_7) && (timeout > 0) ) timeout-- ; //wait HIGH
#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温湿度传感器连接到芯片的PA7引脚,;
- 同时配置PA7引脚和,根据时序图进行相对应的发送和接收;
- **#define delay_us(X) delayd(X*72/5)**可能通过调试计算出来相对准确的延时函数;
- MCU首先发送开始数据(),然后切换到输入模式(),等待DHT11响应;
- DHT11检测到开始信号后,,并等待单线变为高电平后输出(),然后输出()准备;
- 每位数据都以低电平(持续时间为50us)开始,输出0时高电平持续时间为26~28us,输出1时高电平持续时间为70us。
- 最后一位数据输出后(),单线由上拉电阻拉为。
- MCU检测到响应信号从单线读取40位数据,并,如果正确则有效,否则丢弃数据。
三、实现功能过程的注意与学习点
1、注意点
- dht11_read()返回的,已经把8位校验和数据除掉了;
- 分别获取温湿度时,注意向;
2、学习的知识点
- ①根据DHT11传输数据的时序,编写获取DHT11温湿度的驱动;
- ②掌握通过移位获取相对应的温湿度数据;
- ③学会使用while循环等待特定的响应信号;
- ④判断传感器数据输出0或者1时,可以通过判断输出0最大持续时间28us;
❤️ ❤️ ❤️ ❤️ ❤️ ❤️