//51单片机控制温湿度传感器DHT11LCD1602YL-9最小系统。#includereg51.h#includeintrins.htypedefunsignedcharBYTE;typedefunsignedintWORD;#defineuintunsignedint#defineucharunsignedcharsbitio=P1^0;//dht11data端接单片机的P1^0口//sbitrw=P2^1;//一下三行是设置lcd1602的使能端//sbitrs=P2^0;sbitep=P2^2;typedefbitBOOL;//此声明一个布尔型变量即真或假//uchardata_byte;ucharRH,RL,TH,TL;//***************延时函数*************************************voiddelay(ucharms)//延时模块//{uchari;while(ms--)for(i=0;i100;i++);}voiddelay1()//一个for循环大概需要81us12MHz8us{uchari;for(i=0;i1;i++);}//***************************************************************//lcd模块//BOOLlcd_bz()//测试lcd'1'.'0'{BOOLresult;rs=0;//读忙信号rw=1;ep=1;_nop_();_nop_();_nop_();_nop_();result=(BOOL)(P2&0x80);ep=0;result;}voidwrite_cmd(ucharcmd)//写指令//{while(lcd_bz());rs=0;rw=0;ep=0;_nop_();_nop_();P0=cmd;_nop_();_nop_();_nop_();_nop_();ep=1;_nop_();_nop_();_nop_();_nop_();ep=0;}voidwrite_addr(ucharaddr)//写地址//{write_cmd(addr|0x80);//LCD第一行的首地址为0x800x80+0x40=0xc0}voidwrite_byte(uchardat)//写字节//{while(lcd_bz());rs=1;rw=0;ep=0;_nop_();_nop_();P0=dat;_nop_();_nop_();_nop_();_nop_();ep=1;_nop_();_nop_();_nop_();_nop_();ep=0;}voidlcd_init()//lcd初始化//{write_cmd(0x38);//设置LCD5*7点阵表示,数据由8跟线传输delay(1);write_cmd(0x0c);//清除屏幕显示delay(1);write_cmd(0x06);//delay(1);write_cmd(0x01);//delay(1);}voiddisplay(ucharaddr,ucharq)//adderq表示显示的字符或数字//{delay(10);write_addr(addr);write_byte(q);delay(1);//LCD上数值跳变的数度}//**************************dht11测试某块*************************************//voidstart()//开始信号{io=1;delay1();io=0;delay(25);//主机把总线拉低必须大于18msDHT11能检测到起始信号io=1;//20-40usdelay1();//以下三个延时函数差不多为24usdelay1();delay1();}ucharreceive_byte()//接收一个字节//{uchari,temp;for(i=0;i8;i++)//接收8bit的数据{while(!io);//等待50us的低电平开始信号结束delay1();//26us-28usdelay1();delay1();temp=0;//时间为26us-28us数据'0'if(io==1)temp=1;//如果26us-28us'1'while(io);//'0'为26us-28us'1'为70usdata_byte=1;//data_byte|=temp;}returndata_byte;}voidreceive()//接收数据//{ucharT_H,T_L,R_H,R_L,check,num_check,i;start();//开始信号//io=1;//DHT11if(!io)//判断从机是否有低电平响应信号//{while(!io);//判断从机发出80us的低电平响应信号是否结束//while(io);//判断从机发出80usR_H=receive_byte();//湿度高位R_L=receive_byte();//湿度低位T_H=receive_byte();//温度高位T_L=receive_byte();//温度低位check=receive_byte();//校验位io=0;//当最后一bit50us//for(i=0;i7;i++)//差不多50us的延时delay1();io=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;}}}//*****************************************************************************voidmain()//主函数模块//{lcd_init();//初始化LCDwhile(1){receive();//接收数据display(0x00,'R');//LCD的第一行显示display(0x01,':');display(0x02,RH/10+0x30);//0x30LCD1602中0x30的位置放有数字0RH/10+0x30即表示湿度的十位数字在字库RH/10+0x30display(0x03,RH%10+0x30);display(0X04,'%');display(0x40,'T');//LCD的第二行显示display(0x41,':');display(0x42,TH/10+0x30);display(0x43,TH%10+0x30);display(0x44,0xdf);//以下两个是温度单位的处理display(0x45,0x43);}}另附效果图: