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

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);
	}
}
  • 10
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C51单片机可以通过DHT11传感器来实现温湿度监测功能。DHT11是一种数字式温湿度传感器,它可以通过单根数据线来和C51单片机进行通信。 以下是一个基于C51单片机DHT11传感器的温湿度监测程序示例: ``` #include <reg52.h> #define DHT11_PIN P1 // 定义DHT11连接的单片机引脚 // 延时函数 void delay(unsigned int i) { while(i--); } // 发送起始信号 void start() { DHT11_PIN = 0; // 拉低数据线 delay(18); // 持续18ms DHT11_PIN = 1; // 拉高数据线 delay(30); // 持续30us } // 读取DHT11的响应信号 unsigned char check_response() { unsigned char response = 0; delay(40); // 等待DHT11响应信号 if (DHT11_PIN == 0) { // 响应信号为低电平 delay(80); // 等待DHT11发出数据信号 if (DHT11_PIN == 1) { // 数据信号为高电平 response = 1; } } while (DHT11_PIN == 1); // 等待DHT11发送完毕 return response; } // 读取一个字节的数据 unsigned char read_byte() { unsigned char byte = 0; for (unsigned char i = 0; i < 8; i++) { while (DHT11_PIN == 0); // 等待数据位的起始信号 delay(30); // 等待数据位的起始信号结束 if (DHT11_PIN == 1) { // 数据为高电平 byte |= (1 << (7 - i)); // 存储数据 } while (DHT11_PIN == 1); // 等待数据位结束 } return byte; } // 读取温湿度数据 void read_data(unsigned char *data) { start(); // 发送起始信号 if (check_response()) { // 读取响应信号 data[0] = read_byte(); // 读取湿度整数部分 data[1] = read_byte(); // 读取湿度小数部分 data[2] = read_byte(); // 读取温度整数部分 data[3] = read_byte(); // 读取温度小数部分 data[4] = read_byte(); // 读取校验和 } } // 主函数 void main() { unsigned char data[5]; // 存储温湿度数据 while (1) { read_data(data); // 读取温湿度数据 if (data[4] == data[0] + data[1] + data[2] + data[3]) { // 校验数据是否正确 // 将温湿度数据输出到LCD屏幕或串口等 } delay(1000); // 每隔1s读取一次温湿度数据 } } ``` 需要注意的是,DHT11传感器的数据线连接到C51单片机的GPIO口时,需要先使用上拉电阻将GPIO口拉高。在以上示例中,我们将DHT11传感器的数据线连接到了P1口,因此需要使用P1口的上拉电阻。如果使用其他GPIO口,需要相应地修改程序中的引脚定义和上拉电阻设置。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值