主程序:
#include<reg51.h>
#include<intrins.h>
#include"DHT11.H"
#include"1602.H"
#define uchar unsigned char
#define uint unsigned int
sbit S1=P3^1;
sbit S2=P3^2;
uchar wendu[15];
uchar shidu[15];
uchar I1=50;I2=50; //设定初始温湿度报警值
//主函数
void main()
{
initialize_lcd();//初始化LCD1602
while(1)
{
receive();
wendu[0]='w';
wendu[1]='e';
wendu[2]='n';
wendu[3]='d';
wendu[4]='u';
wendu[5]='n';
wendu[5]=':';
wendu[6]=RH/1000+'0'; //温度百位
wendu[7]=RH%1000/100+'0'; //温度十位
wendu[8]=RH%100/10+'0'; //温度个位
wendu[9]='.'; //小数点
wendu[10]=RH%10+'0'; //温度小数点后第一位
lcd_showstring(0,0,wendu);
shidu[0]='s';
shidu[1]='h';
shidu[2]='i';
shidu[3]='d';
shidu[4]= 'u';
shidu[5]= ':';
shidu[6]=TH/1000+'0'; //湿度百位
shidu[7]=TH%1000/100+'0'; //湿度十位
shidu[8]=TH%100/10+'0'; //湿度个位
shidu[9]='.'; //小数点
shidu[10]=TH%10+'0'; //湿度小数点后第一位
lcd_showstring(1,0,shidu);
delay_ms(500);
}
}
DHT11:
#ifndef _DHT11_H_
#define _DHT11_H_
#define uchar unsigned char
#define uint unsigned int
uchar RH,RL,TH,TL;
uchar data_byte;
sbit i0=P1^0; //数据口
void delay_1ms(uint ms)
{
uchar i;
while(ms--)
for (i=0;i<124;i++);
}
void delay_1us(uint us)
{
for(;us>0;us--)
{
_nop_();
}
}
//初始化
void start()//开始信号
{
i0=1;
delay_1us(8);
i0=0;
delay_1ms(25); //拉低至少 18ms 保证能检测到起始信号
i0=1; //检测到开始信号后,将电平拉高20-40us
delay_1us(25); //可替换成20-40us程序
}
uchar receive_byte()//接收一个字节
{
uchar i,temp;
for(i=0;i<8;i++)
{
while(!i0);//等待50us的低电平开始信号结束
delay_1us(27); //开始信号结束后,延时26us-28us
temp=0; //如果时间为26us-28us 则表示接收的数据为‘0’
if(i0==1)
temp=1;//如果时间超过26us-28us 则表示收到的数据为‘1’
while(i0);//等待数据信号高电平, ‘0’为26us-28us;‘1’为70us
data_byte<<=1;//将接收到的数据向高位左移
data_byte|=temp;
}
return data_byte;
}
void receive() //接收数据
{
uchar T_H,T_L,R_H,R_L,check,num_check;
start();//开始信号
i0=1; //主机设为输入 判断从机DHT11的响应信号
if(!i0) //判断是否有响应信号
{
while(!i0);//判断从机发出80us低电平信号是否结束
while(i0);
R_H= receive_byte();//湿度整数
R_L= receive_byte();//湿度小数
T_H= receive_byte();//温度整数
T_L= receive_byte();//温度小数
check= receive_byte();//检验位
i0=0;//当所有的数据接收完成后,将从机电平拉低50us
delay_1us(50); //拉低50us
i0=1;//将从机电平拉低,进入空闲状态
num_check=R_H+R_L+T_H+T_L;
if(num_check=check)//判断读取的数据与校验位是否相同
{
RH=R_H;
RL=R_L;
TH=T_H;
TL=T_L;
check=num_check;
}
}
}
#endif
1602:
#ifndef _LCD1602_H_
#define _LCD1602_H_
#define uchar unsigned char
#define uint unsigned int
sbit RS=P2^0;
sbit RW=P2^1;
sbit EN=P2^2;
void delay_ms(uint ms)
{
uchar i;
while(ms--)
for (i=0;i<120;i++);
}
void delay_us(uint us)
{
for(;us>0;us--)
{
_nop_();
}
}
void lcd_en_write(void)
{
EN=1;
delay_us(20);
EN=0;
delay_us(20);
}
bit busy_wait() //忙等待程序
{
bit lcd_status;
EN=0;
RS=0; //读忙信号
RW=1;
EN=1;
_nop_();
_nop_();
_nop_();
_nop_();
lcd_status=(bit)(P0 &0x80);
EN=0;
return lcd_status;
}
void write_lcd_command(uchar cmd) //写指令
{
busy_wait();
EN=0;
RS=0;
RW=0;
P0=cmd;
lcd_en_write();
}
void write_lcd_data(uchar dat) //写数据
{
busy_wait();
EN=0;
RS=1;
RW=0;
P0=dat;
lcd_en_write();
}
void initialize_lcd() //初始化
{
delay_ms(50);
write_lcd_command(0x38); /*显示模式设置*/
delay_ms(5);
write_lcd_command(0x38);
delay_ms(5);
write_lcd_command(0x38);
delay_ms(5);
write_lcd_command(0x38);
write_lcd_command(0x08); /*显示关闭*/
write_lcd_command(0x01); /*显示清屏*/
write_lcd_command(0x06); /*显示光标移动设置*/
delay_ms(5);
write_lcd_command(0x0C); /*显示开及光标设置*/
}
void lcd_showstring(uchar r,uchar c,uchar *str) //显示位置
{
uchar i=0;
code uchar DDRAM[]={0X80,0XC0};
write_lcd_command(DDRAM[r]| c);
while (*str)
{
write_lcd_data(*str);
str++;
i++;
}
for(;i<16;i++)
write_lcd_data(' ');
}
void lCD_clear(void) //清屏函数
{
write_lcd_command(0x01);
delay_ms(5);
}
#endif |