单片机很好玩7,制作温湿度计,DHT11的使用
发表于: 2019-01-13 19:56:17 | 已被阅读: 23 | 分类于: 单片机
软件总是给人一种“无所不能”的感觉,衣有购物软件,食有外卖软件,住有订房软件,行有打车软件。甚至,想知道电脑的主板温度,还可以下载监控软件查看。
借助外界传感器
看了上一节文章的朋友应该明白,我们之所以能够使用监控软件查看主板温度,是因为电脑主板集成了温度传感器。软件本身是无法主动获取外界环境状态的,例如,如果我想知道现在室内的温度和湿度,该下载哪个软件呢?除非电脑本身延伸出了温度传感器,否则无论哪个软件也不能获得室内的温度和湿度。
RH 表示湿度信息,88% 左右,TM 表示温度,7度左右。
计划使用的还是 51 单片机,传感器是 DHT11。DHT11 数字温湿度传感器是一款含有已校准数字信号输出的温湿度复合传感器,包括一个电阻式感湿元件和一个 NTC 测温元件,并与一个高性能的 8 位单片机连接。DHT11 只有一根数据线,可如下与单片机相连:
编写 C语言代码,启动 DHT11 温湿度传感器
那么怎样使用 51 单片机采集 DHT11 采集的温湿度信息呢?这就需要看它的通信协议了
void dht11_start()
{
P20 = 1;
delay_10us(2000);
P20 = 0;
delay_10us(2000);
P20 = 1;
while(P20);
while(!P20);
}
set_timer0(10);
void delay_10us(unsigned int n)
{
while(n--){
start_timer0();
wait_timer0();
}
}
dht11_start() 函数的逻辑非常简单,先将与 DHT11 数据线连接的 P20 口拉低 20 ms 再拉高,接着的 while(P20) 和 while(!P20) 是等待 DHT11 的响应信号的。
编写C语言代码,读取DHT11温湿度信息
DHT11 启动后,会一次性发送 40 bit 的数据,高位先出,它的数据格式为:
1Byte湿度整数部分 + 1Byte湿度小数部分 + 1Byte温度整数部分 + 1Byte温度小数部分 + 1Byte校验和
那么, 什么样的信号表示 bit 1,什么样的信号表示 bit 0 呢?请看下图:
所以读取一次温湿度信息的 C语言代码可以如下写:
void dht11_read_once(char* dat)
{
unsigned char i=0, j;
char tmp = 0;
while(P20);
for(i=0; i<5; i++){
tmp = 0;
for(j=0;j<8;j++){
while(!P20);
delay_10us(4);
tmp <<= 1;
if(P20)
tmp |= 1;
while(P20);
}
dat[i] = tmp;
}
}
编写C语言代码,将读取到的数据发送到电脑
dht11_read_once() 函数返回的是 5 字节数据,怎样将其组合,发送到电脑呢?其实使用 printf 函数是非常简单,但是经过我的测试,发现该函数消耗的资源太多了,资源匮乏的 51 单片机扛不住,直接罢工,无法正在工作。
所以还是要自己封装函数,上一节封装的 prints 函数只能传输字符串,那么我们就需要再定义一个可以传送数字的函数,请看如下C语言代码:
void printn(unsigned char num)
{
char buf[3] = {0};
buf[0] = num/100 + '0';
buf[1] = (num/10)%10 + '0';
buf[2] = num%10 + '0';
prints(buf);
}
printn() 函数可以把一个 unsigned char 型整数转换为字符发送到串口。所以DHT11的温湿度信息可以按照如下逻辑传输,请看C语言代码:
cks = 0;
cks += dat[0]; cks += dat[1];
cks += dat[2]; cks += dat[3];
if((char)cks == dat[4]){
prints("RH: ");printn(dat[0]);prints(".");printn(dat[1]);prints(" ");
prints("TM: ");printn(dat[2]);prints(".");printn(dat[3]);prints("\r\n");
}else{
prints("capture failed\r\n");
}
整个 main 函数的控制逻辑如下: