九、Proteus817实现51单片机DHT22温湿度读取

前言

最近搜DHT11的时候发现还有个器件DHT22,刚好有前面的DHT11代码,仿真替换器件后,发现代码运行出错,展示的数据是错误的,后面查询得知DHT22的数据格式不一样,解析函数不一致,所以得重新写解析函数。

一、仿真

直接展示仿真的连接吧,具体可以参考本栏前面几章的仿真操作。

二、代码

这里的代码是在DHT11的基础上改的,所以一些函数和文件的DHT11我没去换,你们直接在使用的时候去分别这两个读取函数即可。

这里有几个需要注意的点

1、DHT22的数据是16位的,所以常规的DHT11的char型是不能用的,会导致数据出现问题。

2、另外读取的温湿度需要经过放缩才能使用,比如27.3,其实数据是273,我们在在代码里利用 / 和 % 去处理就可以拿出小数位。

打开keil后新建工程添加文件。

main.c

c 复制代码
#include "intrins.h"
#include "reg52.h"
#include "string.h"
#include "DHT11.h"
#include "uart.h"

void Delay1000ms(void)	//@11.0592MHz
{
	unsigned char data i, j, k;

	_nop_();
	i = 8;
	j = 1;
	k = 243;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}

void main()
{

	int temp, humi, res;
	UART_Init(9600);
	while(1)
	{
		Delay1000ms();//延时
		res = DHT22_Read_Data(&temp,&humi);//读取数据
		if(res == 2)
		{
			UART_SendString("Temp:");
			UART_SendDec(temp/10);
			UART_SendString(".");
			UART_SendDec(temp%10);
			UART_SendString("  Humi:");
			UART_SendDec(humi/10);
			UART_SendString(".");
			UART_SendDec(humi%10);
			UART_SendString("\r\n");
		}
				
	}
}

DHT11.c

c 复制代码
#include "intrins.h"
#include "reg52.h"
#include "string.h"
#include "DHT11.h"
#include "uart.h"

void Delay1000ms(void)	//@11.0592MHz
{
	unsigned char data i, j, k;

	_nop_();
	i = 8;
	j = 1;
	k = 243;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}

void main()
{

	int temp, humi, res;
	UART_Init(9600);
	while(1)
	{
		Delay1000ms();//延时
		res = DHT22_Read_Data(&temp,&humi);//读取数据
		if(res == 2)
		{
			UART_SendString("Temp:");
			UART_SendDec(temp/10);
			UART_SendString(".");
			UART_SendDec(temp%10);
			UART_SendString("  Humi:");
			UART_SendDec(humi/10);
			UART_SendString(".");
			UART_SendDec(humi%10);
			UART_SendString("\r\n");
		}
				
	}
}

DHT11.h

c 复制代码
#ifndef _DHT11_H
#define _DHT11_H

#define uchar unsigned char
#define uint  unsigned int
//两个函数不要同时用
unsigned char DHT11_Read_Data(uchar *temp, uchar *humi);//返回值为读取数据状态----DHT11
unsigned char DHT22_Read_Data(uchar *temp, uchar *humi);//返回值为读取数据状态----DHT22
	
#endif

另外还需要串口

uart.c

c 复制代码
#include "uart.h"
#include "reg52.h"

// ---- 串口初始化 (9600, 11.0592MHz 晶振) ----
void UART_Init(unsigned long baudrate)
{
		unsigned char reload_value;
    SCON = 0x50;    // 模式1, 8位数据, 可变波特率
    TMOD &= 0x0F;
    TMOD |= 0x20;   // 定时器1, 模式2
		// 使用公式计算重载值: TH1 = 256 - (晶振频率)/(384*波特率)
    // 注意: 这里假设使用11.0592MHz晶振
    reload_value = 256 - (11059200UL / (384 * baudrate));
    // 设置定时器1初始值
    TH1 = reload_value;
    TL1 = reload_value;	
		// 启动定时器1
    TR1 = 1;
		// 设置发送中断标志,使能标准库函数(如printf)
    TI = 1;
		// 开启总中断
    EA = 1;
}

// ---- 基础串口发送 ----
void UART_SendChar(unsigned char c)
{
    SBUF = c;
    while(!TI);
  
  TI = 0;
}
void UART_SendString(char *s)
{
    while(*s) UART_SendChar(*s++);
}

// 增强的十进制输出函数(支持更多位数)
void UART_SendDec(unsigned int val)
{
    char buf[6]; // 最大支持65535(5位数)+结束符
    int pos = 0;
    
    if (val == 0) {
        UART_SendChar('0');
        return;
    }
    
    while (val > 0 && pos < 6) {
        buf[pos++] = (val % 10) + '0';
        val /= 10;
    }
    
    while (pos--) {
        UART_SendChar(buf[pos]);
    }
}

// 在uart.h中添加16进制发送函数
void UART_SendHex(unsigned char hex)
{
	unsigned char high, low;
	
	high = hex >> 4;
	low = hex & 0x0F;
	
	if(high < 10)
		UART_SendChar(high + '0');
	else
		UART_SendChar(high - 10 + 'A');
		
	if(low < 10)
		UART_SendChar(low + '0');
	else
		UART_SendChar(low - 10 + 'A');
}

uart.h

c 复制代码
#ifndef _UART_H
#define _UART_H

void UART_Init(unsigned long baudrate);
void UART_SendChar(unsigned char c);
void UART_SendString(char *s);
void UART_SendDec(unsigned int val);
void UART_SendHex(unsigned char hex);
#endif

验证

仿真导入程序后

我们可以看到数据一致,验证成功。

四、总结

DHT22和DHT11的编程区别主要在于数据处理,其他时序基本一致。

相关推荐
国科安芯18 小时前
航天器多路并联大功率电源系统设计与ASP4644均流特性分析
单片机·嵌入式硬件·fpga开发·安全性测试
茯苓gao19 小时前
嵌入式开发笔记:CANopen相关移位运算与通信协议术语详解
网络·嵌入式硬件·学习·信息与通信
梁朝辉1 天前
STM32H750VBT6中ADCINP与INN什么区别
stm32·单片机·嵌入式硬件
省四收割者1 天前
一文详解信号完整性(1)
python·嵌入式硬件·数学建模·信息与通信·信号处理·智能硬件
崇山峻岭之间1 天前
单片机无感FOC驱动之ADC
单片机·嵌入式硬件
Ligocious1 天前
1.点亮一颗小小的LED
单片机·嵌入式硬件
KaifuZeng1 天前
通信与接口协议面试八、CAN通信
单片机·嵌入式硬件·面试·通信与接口协议
智源单片机设计1 天前
基于单片机的直流电机双闭环调速系统设计
单片机·嵌入式硬件
KaifuZeng2 天前
通信与接口协议面试一、基本概念
嵌入式硬件·通信与接口协议
wuyk5552 天前
24. C 语言模块化:不是拆几个.c 文件那么简单
c语言·开发语言·stm32·单片机