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,即12TAUXR &= 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 == 1TI = 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,这里给它30msDelay30ms(); 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]; //humidityvoid check_busy()
{char tmp = 0x80;databuffer = 0x80;while(tmp & 0x80){//1000 0000RS = 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,即12TAUXR &= 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 == 1TI = 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,这里给它30msDelay30ms(); 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)延时 15msDelay15ms();
//(2)写指令 38H(不检测忙信号) Write_Cmd_Func(0x38);
//(3)延时 5msDelay5ms();
//(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(); //初始化LCDDelay1000ms();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);}
}