#include<reg52.h>
#include<intrins.h>
#include<stdio.h>
#define uchar unsigned char
#define uint unsigned int
/********************************************************************/
//LCD_1602_IO口定义
//
sbit rs=P3^5;
sbit lcden=P3^4;
sbit dula=P2^6;
sbit wela=P2^7;
//DHT11_IO定义
//
sbit Temp_data=P2^5;
/*****************************************/
//定义初始化数组
//LCD数组
uchar table1[]="Welcome to ";
uchar table2[]="calculator";
//DHT11数组
unsigned int rec_dat[4];
unsigned char rec_dat_lcd0[6];
unsigned char rec_dat_lcd1[6];
unsigned char rec_dat_lcd2[6];
unsigned char rec_dat_lcd3[6];
/********************************************************************/
void DHT11_delay_us(unsigned char n);
void DHT11_delay_ms(unsigned int z);
void DHT11_start();
unsigned char DHT11_rec_byte();
void DHT11_receive();
void InitUART(void);
void bindec_init(uint a,uint n);
void bindec_XSD_init(uint a,uint n);
//延时函数
//延时10us
//延时100us
void delay(uint x) //10us
{
uint a,b;
for(a=x;a>0;a--)
for(b=10;b>0;b--);
}
void delay1(uint x) //100us
{
uint a,b;
for(a=x;a>0;a--)
for(b=100;b>0;b--);
}
/********************************************************************/
/********************************************************************/
//LCD——1602函数
//设置屏幕显示位置
//写数据
void write_com(uchar com)
{
P0=com;
rs=0;
lcden=0;
delay(10);
lcden=1;
delay(10);
lcden=0;
}
void write_date(uchar date)
{
P0=date;
rs=1;
lcden=0;
delay(10);
lcden=1;
delay(10);
lcden=0;
}
//LCD_1602初始化
void LCD_init()
{
dula=0;
wela=0;
write_com(0x38);
delay(20);
write_com(0x0f);
delay(20);
write_com(0x0c);
delay(20);
write_com(0x01);
delay(20);
}
/********************************************************************/
//DHT11初始化
//DHT11起始信号
void DHT11_start()
{
Temp_data=1;
DHT11_delay_us(2);
Temp_data=0;
DHT11_delay_ms(20);
Temp_data=1;
DHT11_delay_us(13);
}
//接收一个字节
unsigned char DHT11_rec_byte()
{
unsigned char i,dat;
for(i=0;i<8;i++)
{
while(!Temp_data);
DHT11_delay_us(8);
dat<<=1;
if(Temp_data==1)
{
dat+=1;
}
while(Temp_data);
}
return dat;
}
//接收温湿度数据
void DHT11_receive()
{
unsigned int R_H,R_L,T_H,T_L;
unsigned char RH,RL,TH,TL,revise;
DHT11_start();
Temp_data=1;
if(Temp_data==0)
{
while(Temp_data==0); //等待拉高
DHT11_delay_us(40); //拉高后延时80us
R_H=DHT11_rec_byte(); //接收湿度高八位
R_L=DHT11_rec_byte(); //接收湿度低八位
T_H=DHT11_rec_byte(); //接收温度高八位
T_L=DHT11_rec_byte(); //接收温度低八位
revise=DHT11_rec_byte(); //接收校正位
DHT11_delay_us(25); //结束
if((R_H+R_L+T_H+T_L)==revise) //校正
{
RH=R_H;
RL=R_L;
TH=T_H;
TL=T_L;
}
rec_dat[0]=RH;
rec_dat[1]=RL;
rec_dat[2]=TH;
rec_dat[3]=TL;
}
}
//延时us --2*n+5us
void DHT11_delay_us(unsigned char n)
{
while(--n);
}
//延时ms
void DHT11_delay_ms(unsigned int z)
{
unsigned int i,j;
for(i=z;i>0;i--)
for(j=110;j>0;j--);
}
//
void bindec_init(uint a,uint n) //显示十位和个位
{
int b,c,d;
// write_com(0x80+a);
// b=n/100+0x30; /// 显示百位 //+0x30就是把百位转换成字符了
// write_date(b);
// delay(20);
write_com(0x80+a+1);
c=n/10%10+0x30; // 显示十位:
write_date(c);
delay(20);
write_com(0x80+a+2);
d=n%10+0x30; /显示个位:
write_date(d);
delay(20);
write_com(0x80+a+3);
write_date(0x2E); //显示小数点
}
void bindec_XSD_init(uint a,uint n) //显示小数点后两位
{
int b,c,d;
// write_com(0x80+a);
// b=n/100+0x30; /// 显示百位 //+0x30就是把百位转换成字符了
// write_date(b);
// delay(20);
write_com(0x80+a+1);
c=n/10%10+0x30; // 显示十位:
write_date(c);
delay(20);
write_com(0x80+a+2);
d=n%10+0x30; /显示个位:
write_date(d);
delay(20);
}
/********************************************************************/
void main()
{
uchar a;
int b,c,d;
LCD_init(); //LCD1602初始化
InitUART();
P1=0xf0;
EA = 1; //开总中断
write_com(0x80+0);
write_date('H');
delay(20);
write_com(0x80+1);
write_date(0x3a);
delay(20);
write_com(0x80+8);
write_date('T');
delay(20);
write_com(0x80+9);
write_date(0x3a);
delay(20);
while(1)
{
DHT11_delay_ms(150);
DHT11_receive();
//write_com(0x80+0x01);
bindec_init(0x01,rec_dat[0]);
bindec_XSD_init(0x04,rec_dat[1]);
bindec_init(0x09,rec_dat[2]);
bindec_XSD_init(0x0C,rec_dat[3]);
//下面通过串口助手打印温度
printf("Humi");
printf("Humi:%d.%d \n",rec_dat[0],rec_dat[1]);
printf("Temp:%d.%d °C\n",rec_dat[2],rec_dat[3]);
}
}
//
void InitUART(void)//使用定时器1作为串口波特率发生器
{
SCON=0x40; //串口通信工作方式1
REN=1; //允许接收
TMOD=0x20; //定时器1的工作方式2
TH1=0xF3,TL1=0xF3;
TI=1;
//这里一定要注意
TR1=1;
}