最近在做大创,要用到DHT11温湿度传感器,发现有点问题解决不了。可以使用。写的程序(主要是DHT11部分)发到网上供大家参考一下,抛砖引玉看看大家有没有什么好的思路。
启动一次DHT11温湿度采集
/*****************************************************************
函数名称:static void DHT11_Init()
函数功能:启动一次温湿度采集
输入参数:无
返回值 :无
*****************************************************************/
static void DHT11_Start()
{
DHT11_DQ = LOW; // 主机把总线拉低等待DHT11响应
DHT11_Delayms(18); // 主机把总线拉低必须大于18ms
DHT11_DQ = HIGH; // 主机开始信号结束
DHT11_Delayus(40); // 主机把总线拉高等待20-40us
while(!DHT11_DQ); // DHT11响应输出 (低电平,80us)
while(DHT11_DQ); // DHT11拉高延时准备输出 (高电平,80us)
while(!DHT11_DQ); // DHT11开始传输数据 (低电平,50us)
}
?开始读取温湿度数据并保存,最后进行校验。有中断参与时,在读取温度时一定要关闭中断,不然会出错。
/*****************************************************************
函数名称:static void DHT11_Read(Dht_t* dht11)
函数功能:温湿度读取
输入参数:dht11:DHT11结构体变量
返回值 :无
*****************************************************************/
static void DHT11_Read(Dht_t* dht11)
{
uint8_t i, mask;
static uint8_t Data_Ori_t[5];
EA = 0; // 在读取温湿度数据时关闭中断
for(i = 0; i < 5; i ++) // 高位在前,逐位读取,将DHT11的数据读取到dht11.Check数组上
{
for(mask = 0X80; mask != 0x00; mask >>= 1)
{
DHT11_Delayus(28); // 延时28us
if(DHT11_DQ == 1) // 看DHT11_DQ是否还输出高电平
{
Data_Ori_t[i] |= mask; // 还是高电平的话则此位为高
while(DHT11_DQ); // 等待DHT11输出完此次高电平 (70us - 28us)
}
while(!DHT11_DQ); // 准备发送数据,每一bit数据都以50us低电平时隙开始
}
}
EA = 1; // 在读取温湿度数据时关闭中断
// 校验数据,8bit校验和 = 8bit湿度整数数据 + 8bit湿度小数数据 + 8bi温度整数数据 + 8bit温度小数数据
if(Data_Ori_t[4] == Data_Ori_t[0] + Data_Ori_t[1] + Data_Ori_t[2] + Data_Ori_t[3])
{
dht11->humidity = Data_Ori_t[0] + Data_Ori_t[1]/256.0; // 湿度值保存,整数加小数
dht11->temperature = Data_Ori_t[2] + Data_Ori_t[3]/256.0; // 温度值保存,整数加小数
for(i = 0; i < 5; i ++)
{
dht11->Data_Ori[i] = Data_Ori_t[i]; // 原始数据保存
Data_Ori_t[i] = 0; // 原数据临时变量复位
}
}
}
整合为DHT11_Acqu函数
/*****************************************************************
函数名称:void DHT11_Acqu(Dht_t* dht11)
函数功能:温湿度采集
输入参数:dht11:DHT11结构体变量
返回值 :无
*****************************************************************/
void DHT11_Acqu(Dht_t* dht11)
{
DHT11_Start(); // 启动一次温湿度采集
DHT11_Read(dht11); // DHT11读取温湿度
}
?dht11结构体类型及变量定义
/****结构体定义****/
typedef struct
{
float humidity;
float temperature;
uint8_t Data_Ori[5];
}Dht_t;
// 定义DHT11结构体变量
Dht_t dht11 =
{
0.0, // 湿度
0.0, // 温度
{0}, // 5个字节的源数据(湿度高8位+湿度低8位+温度高8位+温度低8位+校验位)
};
主函数,将采集的温湿度数据显示到LCD1602上
#include <DHT11.h>
#include <LCD1602.h>
#include <public.h>
void main()
{
// 变量声明/定义
extern Dht_t dht11;
uint8_t Dis[30];
uint16_t count = 0;
// LCD1602初始化
LCD1602_Init();
// // 提前进行一次转换
// DHT11_Acqu(&dht11);
// sprintf(s, "%2.0f %2.2f", dht11.humidity, dht11.temperature);
// LOOP
while(1)
{
count --;
if(!count) // 每隔一段时间采样一次
{
count --;
DHT11_Acqu(&dht11); // 更新温湿度
// 将湿度信息格式化输出到数组Dis
sprintf(Dis, "HUMI: %2.0f%%", dht11.humidity);
LCD1602_Print(0, 0, Dis); // 第一行显示湿度
// 将温度信息格式化输出到数组Dis,0XDF为"°"的ASCII码值
sprintf(Dis, "TEMP: %2.2f%cC", dht11.temperature, (uint8_t)(0xDF));
LCD1602_Print(1, 0, Dis); // 第二行显示温度
}
}
}
关于函数前面加static修饰词:C语言中的静态(static)函数_yubinghang93的博客-CSDN博客
主要是这一点:“静态函数会被自动分配在一个一直使用的存储区,直到程序结束才从内存消失,避免调用函数时压栈出栈,速度快很多。”
实际效果
源程序
链接:百度网盘 请输入提取码 提取码:gfjk
?现在不知道要怎么改能在读取温湿度时不关闭中断,也就是去掉DHT11_Read函数里的EA = 0;、EA = 1;这两条语句。大家有什么思路吗?
|