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
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!