C51--DHT11数据读取并通过串口上传--LCD显示

2023-12-13 13:44:21

DHT11数据读取并通过串口上传

#include "reg52.h"
#include <intrins.h>

sbit ledOne = P3^7;
sbit DHT = P3^3;			//模块的data接在c51的P3.3口

char datas[5];

sfr AUXR = 0x8E;

//串口初始化
void UartInit(void)		//9600bps@11.0592MHz
{
	PCON &= 0x7F;		//波特率不倍速
	SCON = 0x50;		//8位数据,可变波特率
	AUXR &= 0xBF;		//定时器1时钟为Fosc/12,即12T
	AUXR &= 0xFE;		//串口1选择定时器1为波特率发生器
	TMOD &= 0x0F;		//清除定时器1模式位
	TMOD |= 0x20;		//设定定时器1为8位自动重装方式
	TL1 = 0xFD;		//设定定时初值
	TH1 = 0xFD;		//设定定时器重装值
	ET1 = 0;		//禁止定时器1中断
	TR1 = 1;		//启动定时器1
}


void sendByte(char data_msg)
{
	//往发送缓冲区中写入数据,就完成了数据的发送
	SBUF = data_msg;

	while(!TI);		//超声波中,用while等待,发送成功后T1 == 1
	
	TI = 0;		
}

void sendString(char* str)
{
	while(*str != '\0'){
		sendByte(*str);
		str++;
	}
}


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

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


void Delay30ms()		//@11.0592MHz
{
	unsigned char i, j;

	i = 54;
	j = 199;
	do
	{
		while (--j);
	} while (--i);
}

void Delay60us()		//@11.0592MHz
{
	unsigned char i;

	i = 25;
	while (--i);
}

void Delay40us()		//@11.0592MHz
{
	unsigned char i;

	_nop_();
	i = 15;
	while (--i);
}


//开始
void DTH11_Start()
{
	
	DHT = 1;			//开始处于 1 位
	DHT = 0;			//拉低至少18ms,这里给它30ms
	Delay30ms();		
	DHT = 1;			//vcc拉高20-40us
	//DHT响应信号,将高电平拉低持续80us(在40--80us之间读取:低电平——模块存在)
	//所以在60us的时候读取
	Delay60us();		
	while(DHT);		//卡点,当不满足while时,信号拉低
	while(!DHT);		//卡点,当不满足while时,信号拉高
	while(DHT);			//卡点,当不满足while时,信号拉低
	while(!DHT);		//卡点,当不满足while时,信号拉高
}

//传输数据
void Read_Data_From_DHT()
{
	//读取数据需要,读5轮,一轮读8次
	int i;		//轮
	int j;		//一轮多少次
	char tmp;	//tmp移位获取数据
	char flag;
	
	DTH11_Start();				//每次读取都需要发送开始
	for(i = 0;i < 5;i++){
		
		for(j = 0;j < 8;j++){
			while(!DHT);		//卡点,当不满足while时,信号拉高
			Delay40us();		//在60um后读取数据,低电平为0,高电平为1。
			if(DHT == 1){
				flag = 1;
				while(DHT);
			}else{
				flag = 0;
			}
			tmp = tmp << 1;		//tmp左移一位
			tmp |= flag;
		}
		datas[i] = tmp;
	}
}

void main()
{
	ledOne = 1;			//灭灯
	UartInit();			//初始化串口
	Delay1000ms();
	Delay1000ms();
	
	while(1){
		Delay1000ms();
		Read_Data_From_DHT();
		sendString("shidu:");
		sendByte(datas[0]/10 + 0x30);		//湿度整数位
		sendByte(datas[0]%10 + 0x30);
		sendByte('.');
		sendByte(datas[1]/10 + 0x30);		//湿度小数位
		sendByte(datas[1]%10 + 0x30);
		sendString("\r\n");
		sendString("wendu:");
		sendByte(datas[2]/10 + 0x30);		//温度整数位
		sendByte(datas[2]%10 + 0x30);
		sendByte('.');
		sendByte(datas[3]/10 + 0x30);		//温度小数位
		sendByte(datas[3]%10 + 0x30);
		sendString("\r\n");
	}
}

LCD显示温湿度

LCD1602显示屏与C51的连接:

电源:
VSS——GND
VDD——5V
对比度:
VO——GND
控制线:
RS——P1.0
RW——P1.1
E——P1.4
背光灯:
ELA——5V``
ELK——GND
数据:
D0–D7——P0.0–P0.7

LCD显示温湿度

#include "reg52.h"
#include <intrins.h>

sbit ledOne = P3^7;
sbit DHT = P3^3;			//模块的data接在c51的P3.3口

char datas[5];

sfr AUXR = 0x8E;

#define databuffer  P0 //定义8位数据线,Po端口组
sbit RS = P1^0;
sbit RW = P1^1;
sbit EN = P1^4;

char wendu[13];		//temperature
char shidu[13];		//humidity

void check_busy()
{
	char tmp = 0x80;
	databuffer = 0x80;
	
	while(tmp & 0x80){//1000 0000
		RS = 0;
		RW = 1;
		EN = 0;
		_nop_();
		EN = 1;
		_nop_();
		_nop_();
		tmp = databuffer;
		EN = 0;
		_nop_();
	}
}

void Write_Cmd_Func(char cmd)
{
	check_busy();
	RS = 0;
	RW = 0;
	
	EN = 0;
	_nop_();
	databuffer = cmd;
	_nop_();
	EN = 1;
	_nop_();
	_nop_();
	EN = 0;
	_nop_();	
}

void Write_Data_Func(char dataShow)
{
	check_busy();
	RS = 1;
	RW = 0;
	
	EN = 0;
	_nop_();
	databuffer = dataShow;
	_nop_();
	EN = 1;
	_nop_();
	_nop_();
	EN = 0;
	_nop_();	
}

void Delay15ms()		//@11.0592MHz
{
	unsigned char i, j;

	i = 27;
	j = 226;
	do
	{
		while (--j);
	} while (--i);
}
void Delay5ms()		//@11.0592MHz
{
	unsigned char i, j;

	i = 9;
	j = 244;
	do
	{
		while (--j);
	} while (--i);
}


//串口初始化
void UartInit(void)		//9600bps@11.0592MHz
{
	PCON &= 0x7F;		//波特率不倍速
	SCON = 0x50;		//8位数据,可变波特率
	AUXR &= 0xBF;		//定时器1时钟为Fosc/12,即12T
	AUXR &= 0xFE;		//串口1选择定时器1为波特率发生器
	TMOD &= 0x0F;		//清除定时器1模式位
	TMOD |= 0x20;		//设定定时器1为8位自动重装方式
	TL1 = 0xFD;		//设定定时初值
	TH1 = 0xFD;		//设定定时器重装值
	ET1 = 0;		//禁止定时器1中断
	TR1 = 1;		//启动定时器1
}


void sendByte(char data_msg)
{
	//往发送缓冲区中写入数据,就完成了数据的发送
	SBUF = data_msg;

	while(!TI);		//超声波中,用while等待,发送成功后T1 == 1
	
	TI = 0;		
}

void sendString(char* str)
{
	while(*str != '\0'){
		sendByte(*str);
		str++;
	}
}


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

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


void Delay30ms()		//@11.0592MHz
{
	unsigned char i, j;

	i = 54;
	j = 199;
	do
	{
		while (--j);
	} while (--i);
}

void Delay60us()		//@11.0592MHz
{
	unsigned char i;

	i = 25;
	while (--i);
}

void Delay40us()		//@11.0592MHz
{
	unsigned char i;

	_nop_();
	i = 15;
	while (--i);
}


//开始
void DTH11_Start()
{
	
	DHT = 1;			//开始处于 1 位
	DHT = 0;			//拉低至少18ms,这里给它30ms
	Delay30ms();		
	DHT = 1;			//vcc拉高20-40us
	//DHT响应信号,将高电平拉低持续80us(在40--80us之间读取:低电平——模块存在)
	//所以在60us的时候读取
	Delay60us();		
	while(DHT);		//卡点,当不满足while时,信号拉低
	while(!DHT);		//卡点,当不满足while时,信号拉高
	while(DHT);			//卡点,当不满足while时,信号拉低
	while(!DHT);		//卡点,当不满足while时,信号拉高
}

//传输数据
void Read_Data_From_DHT()
{
	//读取数据需要,读5轮,一轮读8次
	int i;		//轮
	int j;		//一轮多少次
	char tmp;	//tmp移位获取数据
	char flag;
	
	DTH11_Start();				//每次读取都需要发送开始
	for(i = 0;i < 5;i++){
		
		for(j = 0;j < 8;j++){
			while(!DHT);		//卡点,当不满足while时,信号拉高
			Delay40us();		//在60um后读取数据,低电平为0,高电平为1。
			if(DHT == 1){
				flag = 1;
				while(DHT);
			}else{
				flag = 0;
			}
			tmp = tmp << 1;		//tmp左移一位
			tmp |= flag;
		}
		datas[i] = tmp;
	}
}

void LCD1602_INIT()
{
	//(1)延时 15ms
	Delay15ms();
//(2)写指令 38H(不检测忙信号) 
	Write_Cmd_Func(0x38);
//(3)延时 5ms
	Delay5ms();
//(4)以后每次写指令,读/写数据操作均需要检测忙信号
//(5)写指令 38H:显示模式设置
	Write_Cmd_Func(0x38);
//(6)写指令 08H:显示关闭
	Write_Cmd_Func(0x08);
//(7)写指令 01H:显示清屏
	Write_Cmd_Func(0x01);
//(8)写指令 06H:显示光标移动设置
	Write_Cmd_Func(0x06);
//(9)写指令 0CH:显示开及光标设置}
	Write_Cmd_Func(0x0c);
}



void LCD1602_showLine(char row, char col, char *string)
{
	
	switch(row){

		case 1:
				Write_Cmd_Func(0x80+col);
				while(*string){
					Write_Data_Func(*string);
					string++;
				}
				break;
		
		case 2:
				Write_Cmd_Func(0x80+0x40+col);
				while(*string){
					Write_Data_Func(*string);
					string++;
				}
				break;
	
	}
}

void build_datas()
{
	shidu[0] = 's';
	shidu[1] = 'h';
	shidu[2] = 'i';
	shidu[3] = 'd';
	shidu[4] = 'u';
	shidu[5] = ':';
	shidu[6] = datas[0]/10 + 0x30;		//湿度整数位
	shidu[7] = datas[0]%10 + 0x30;
	shidu[8] = '.';
	shidu[9] =  datas[1]/10 + 0x30;		//湿度小数位
	shidu[10] = datas[1]%10 + 0x30;
	shidu[11] = '%';
	shidu[12] = '\0';
	
	wendu[0] = 'w';
	wendu[1] = 'e';
	wendu[2] = 'n';
	wendu[3] = 'd';
	wendu[4] = 'u';
	wendu[5] = ':';
	wendu[6] = datas[2]/10 + 0x30;		//温度整数位
	wendu[7] = datas[2]%10 + 0x30;
	wendu[8] = '.';
	wendu[9] =  datas[3]/10 + 0x30;		//温度小数位
	wendu[10] = datas[3]%10 + 0x30;
	wendu[11] = 'C';
	wendu[12] = '\0';
}

void main()
{
	Delay1000ms();
	
	UartInit();			//初始化串口
	LCD1602_INIT();		//初始化LCD
	Delay1000ms();
	Delay1000ms();
	ledOne = 0;			//亮灯
	
	while(1){
		Delay1000ms();
		Read_Data_From_DHT();
		build_datas();
		sendString(shidu);
		sendString("\r\n");
		sendString(wendu);
		sendString("\r\n");
		LCD1602_showLine(1,2,shidu);
		LCD1602_showLine(2,2,wendu);
	}
}

文章来源:https://blog.csdn.net/weixin_48208102/article/details/134729293
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。