实现通过LCD1602显示DHT11采集的温湿度数据
#include <REGX52.H>
#include "intrins.h"
sbit Datas = P2^0;
sbit RS = P2^1;
sbit RW = P2^2;
sbit E = P2^3;
sbit fan = P2^4;
char datas[5];
char Tem[8];
char hum[8];
sfr AUXR = 0X8E;
#define data_DB P0
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 Delay35ms() //@11.0592MHz
{
unsigned char i, j;
i = 63;
j = 190;
do
{
while (--j);
} while (--i);
}
void Delay45us() //@11.0592MHz
{
unsigned char i;
i = 18;
while (--i);
}
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);
}
/*DHT11启动信号*/
void dht11_start()
{
Datas = 1;
Datas = 0;
Delay35ms();
Datas = 1;
while(Datas); //根据时序图可知,当datas由高电平运行到低电平时执行下方的程序,所以写出(while(datas))。
while(!Datas);
while(Datas);
}
/*串口初始化*/
void UartInit()
{
SCON = 0x40;
TMOD &= 0x0F;
TMOD |= 0x20;
TL1 = 0xFD;
TH1 = 0xFD;
ET1 = 0;
TR1 = 1;
}
/*串口数据发送:字节发送*/
void sendbyte(data_msg)
{
SBUF = data_msg; //将形式参数data_msg传送到SBUF
while(TI == 0); //当一个字节传输完毕之后,TI被自动置位
TI = 0; //中断请求结束之后,软件自动复位为0
}
/*字符串数据发送*/
void sendstring(char* string)
{
while( *string != '\0')
{
sendbyte(*string);
string++;
}
}
/*检测LCD是否忙碌*/
void check_busy()
{
char tep = 0x80;
char data_DB = 0X80;
while(tep & 0x80)
{
RS = 0;
RW = 1;
E = 0;
_nop_();
tep = data_DB;
E = 1;
_nop_();
E = 0;
_nop_();
}
}
/*LCD写入数据函数*/
void write_data(char datashow)
{
check_busy();
RS = 1;
RW = 0;
E = 0;
_nop_();
data_DB = datashow;
E = 1;
_nop_();
E = 0;
_nop_();
}
/*LCD写入指令函数*/
void write_cmd(char cmd)
{
check_busy();
RS = 0;
RW = 0;
E = 0;
_nop_();
data_DB = cmd;
E = 1;
_nop_();
E = 0;
_nop_();
}
/*LCD1602初始化函数*/
void LCD_1602_begin()
{
Delay15ms();
write_cmd(0x38);
Delay5ms();
write_cmd(0x38);
write_cmd(0x08);
write_cmd(0x01);
write_cmd(0x06);
write_cmd(0x0c);
}
/*读取DHT11数据*/
void read_dht11datas()
{
char i;//定义轮数
char j;//每轮数据读取的位数
char temp;
char flag;
dht11_start();
for(i=0;i<5;i++)
{
for(j=0;j<8;j++)
{
while(!Datas);
Delay45us();
if(Datas == 1)
{
flag = 1;
while(Datas);
}
else
{
flag = 0;
}
temp = temp << 1;
temp |= temp;
}
datas[i] = temp;
}
}
/*LCD1602显示方式设定函数*/
void LCD1602_datashow_line(char hang,char lie,char *string)
{
switch(hang)
{
case 1:
write_cmd(0x80+lie);
while(*string)
{
write_data(*string);
string++;
}
break;
case 2:
write_cmd(0x80+0x40+lie);
while(*string)
{
write_data(*string);
string++;
}
break;
}
}
/*数据组合函数
为了保障ascll码不会混乱,因此在每个数据高位都会加0x30*/
void data_build()
{
hum[0] = 'H';
hum[1] = datas[0]/10 + 0x30;
hum[2] = datas[0]%10 + 0x30;
hum[3] = '.';
hum[4] = datas[1]/10 + 0x30;
hum[5] = datas[1]%10 + 0x30;
hum[6] = '%';
hum[7] = '\0';
Tem[0] = 'T';
Tem[1] = datas[2]/10 + 0x30;
Tem[2] = datas[2]%10 + 0x30;
Tem[3] = '.';
Tem[4] = datas[3]/10 + 0x30;
Tem[5] = datas[3]%10 + 0x30;
Tem[6] = 'C';
Tem[7] = '\0';
}
void main()
{
Delay1000ms();
LCD_1602_begin();
UartInit();
Delay1000ms();
Delay1000ms();
while(1)
{
Delay1000ms();
read_dht11datas();
if(datas[2 > 24])
{
fan = 0;
}
else
{
fan = 1;
}
data_build();
sendstring(hum);
sendstring("\r\n");
sendstring(Tem);
sendstring("\r\n");
LCD1602_datashow_line(1,2,Tem);
LCD1602_datashow_line(2,2,hum);
}
}