找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 6843|回复: 4
打印 上一主题 下一主题
收起左侧

51单片机DHT11温湿度传感器通过1602显示

[复制链接]
跳转到指定楼层
楼主
ID:395212 发表于 2018-9-7 23:43 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
这是智能家居系统中窗户开关控制部分,适用于51单片机,全部原创。DHT11温湿度传感器通过1602显示。

单片机源程序如下:
  1. //11.0592MHz单片机STC89C52RC;DHT11在LCD1602显示
  2. #include <reg52.h>
  3. #include <intrins.h>
  4. #define uchar unsigned char
  5. #define uint unsigned int
  6. /***********端口定义**************/
  7. sbit RS=P2^0;//1602RS端口
  8. sbit RW=P2^1;//1602RW端口
  9. sbit  E=P2^5;//1602E端口
  10. //LCD1602数据口接P0
  11. sbit IO=P2^7;//dht11数据口
  12. sbit I1=P2^3;

  13. sbit l1=P1^0;
  14. sbit l2=P1^1;
  15. /*sbit l3=P1^2;
  16. sbit l4=P1^3;
  17. sbit l5=P1^4;
  18. sbit l6=P1^5;
  19. sbit l7=P1^6;
  20. sbit l8=P1^7;  */

  21. bit  RXAAOK;                        //接收到0XAA开头标志
  22. bit  RXFRMOK;                       //接收一帧完整数据标
  23. uchar RXBUF[32],TXBUF[32];  //接收缓存
  24. uchar RX_P;                         //数据个数
  25.               
  26. /**********变量定义*****************/
  27. uint timeout;//溢出
  28. uchar RH_H;//温度整数位
  29. uchar RH_L;// 温度小数位
  30. uchar T_H;// 湿度整数位
  31. uchar T_L;// 湿度小数位
  32. uchar Cheakdata;//校验位

  33. uint timeout1;//溢出
  34. uchar RH_H1;//温度整数位
  35. uchar RH_L1;// 温度小数位
  36. uchar T_H1;// 湿度整数位
  37. uchar T_L1;// 湿度小数位
  38. uchar Cheakdata1;//校验位

  39. uchar PM2_5;
  40. uchar PM10;

  41. /**********************************/
  42. /*****延时1ms******/
  43. void Delay1ms(uchar c)                //1ms延时
  44. {
  45.         uchar i, j;
  46. for(;c>0;c--)
  47.         {
  48.                  _nop_();
  49.            i = 2;
  50.            j = 199;
  51.            do
  52.           {
  53.                  while (--j);
  54.          } while (--i);
  55.   }
  56. }
  57. /*****延时10us******/
  58. void Delay10us(void)                //10us延时
  59. {
  60.         uchar i;
  61.         {
  62.         i = 2;
  63.         while (--i);
  64.         }
  65. }


  66. void UART_init()
  67. {
  68.         TMOD = 0x20;        //T1工作模式2 8位自动重装
  69.         TH1 = 0xfd;                //11111101
  70.         TL1 = 0xfd;         //比特率9600
  71.         TR1 = 1;                //启动T1定时器
  72.         SM0 = 0;               
  73.         SM1 = 1;                //串口工作方式1 10位异步
  74.         REN = 1;                //串口允许接受
  75.         EA = 1;
  76.         ES = 1;
  77. }




  78. void UARTO_ISR() interrupt 4  //接收中断
  79. {
  80.     uchar i,j;         //用处提取接收缓冲器的字符  
  81.     if(RI)  
  82.     {
  83.      i=SBUF;        //提取字符
  84.      RI=0;
  85.      if(RXFRMOK == 0)   //判断是否接收到起始字符0XAA
  86.      {  
  87.          if(RXAAOK)     //如果接收到0XAA,继续接收后面的字符
  88.          {
  89.           RXBUF[RX_P]=i;                                                   //字符存入数组
  90.           if((RX_P>3)&&(RXBUF[RX_P] == 0xab) )  //判断是是否接收完毕一帧数据
  91.           {
  92.            RXFRMOK=1;             //如果接收完成,置位RXFRMOK;
  93.            RXAAOK=0;              //清零开始标志位RXAAOK
  94.           }
  95.           RX_P++;                    //接收计数器加一                                
  96.           }
  97.           if(!RXAAOK&&(i==0xaa))  
  98.            {
  99.              RXAAOK=1;
  100.              RX_P=0;
  101.              }
  102.            }
  103.         }
  104.         for(j = 0;j < 4;j++)
  105.         {
  106.                 TXBUF[j] = RXBUF[j+1];         //提取中间四位
  107.         }

  108.         /*for(j = 0;j < 4;j++)
  109.         {
  110.                 SBUF = TXBUF[j];
  111.                 while(!TI);
  112.                 TI = 0;
  113.         } */
  114. }


  115. /****1602忙检测函数****/
  116. uchar LCD1602_BUSY()//读状态
  117. {
  118.         uchar state;
  119.   RS=0;
  120.         RW=1;
  121.         P0=0xFF;
  122.         E=1;
  123.         Delay1ms(1);
  124.         E=0;
  125.         return state;
  126. }
  127. /*****1602写数据函数带忙检测*****/
  128. void LCD1602_WRITE_DATA_BUSY(uchar databuf)
  129. {
  130.         while((LCD1602_BUSY()&&0x80)==0x80);
  131.   RS=1;
  132.         RW=0;
  133.         P0=databuf;
  134.         E=1;
  135.         E=0;
  136. }
  137. /****1602写指令函数******/
  138. void LCD1602_WRITE_COM(uchar combuf)
  139. {
  140.   RS=0;
  141.         RW=0;
  142.         P0=combuf;
  143.         E=1;
  144.         E=0;
  145. }
  146. /****1602写指令函数带忙检测******/
  147. void LCD1602_WRITE_COM_BUSY(uchar combuf)
  148. {
  149.         while((LCD1602_BUSY()&&0x80)==0x80);
  150.   RS=0;
  151.         RW=0;
  152.         P0=combuf;
  153.         E=1;
  154.         E=0;
  155. }
  156. /****1602初始化函数******/
  157. void LCD1602_init(void)
  158. {
  159.   Delay1ms(15);//15ms
  160.         LCD1602_WRITE_COM(0x38);
  161.         Delay1ms(5);//5ms
  162.         LCD1602_WRITE_COM(0x38);
  163.         Delay1ms(5);//5ms
  164.         LCD1602_WRITE_COM(0x38);
  165.         LCD1602_WRITE_COM_BUSY(0x38);
  166.         LCD1602_WRITE_COM_BUSY(0x08);
  167.         LCD1602_WRITE_COM_BUSY(0x01);
  168.         LCD1602_WRITE_COM_BUSY(0x06);
  169.         LCD1602_WRITE_COM_BUSY(0x0C);
  170. }
  171. /*******DHT11读字节**************/
  172. uchar ReadByte(void)
  173. {
  174.         uchar i;
  175.         uchar buf=0;
  176.         for(i=0;i<8;i++)
  177.         {
  178.                 IO=1;
  179.                 timeout=0;
  180.                 while((IO==0)&&((timeout++)<500));
  181.            Delay10us();
  182.                 Delay10us();
  183.                 Delay10us();
  184.                 _nop_();//31us
  185.            buf=buf<<1;
  186.            if(IO==1)
  187.                  {
  188.                          buf=buf|0x01;
  189.                  }
  190.                  timeout=0;
  191.                 while((IO==1)&&((timeout++)<500));
  192.         }
  193.           return buf;
  194. }
  195. /*******DHT11读温湿度************/
  196. uchar ReadRH(void)
  197. {
  198.         IO=0;
  199.   Delay1ms(20);//20ms
  200.         IO=1;
  201.         Delay10us();
  202.         Delay10us();
  203.         Delay10us();
  204.         Delay10us();
  205.         Delay10us();//50us
  206.         if(IO==0)
  207.         {
  208.                 timeout=0;
  209.                 while((IO==0)&&((timeout++)<500));
  210.                 timeout=0;
  211.                 while((IO==1)&&((timeout++)<500));
  212.                 RH_H=ReadByte();
  213.                 RH_L=ReadByte();
  214.                 T_H=ReadByte();
  215.                 T_L=ReadByte();
  216.                 Cheakdata=ReadByte();
  217.                 if(Cheakdata==RH_H+RH_L+T_H+T_L)
  218.                 {return 1;}//成功
  219.                 else
  220.                 {return 0;}//失败
  221.         }
  222.         else
  223.                 return 0;//失败
  224. }




  225. /*******DHT11读字节**************/
  226. uchar ReadByte1(void)
  227. {
  228.         uchar i;
  229.         uchar buf=0;
  230.         for(i=0;i<8;i++)
  231.         {
  232.                 I1=1;
  233.                 timeout=0;
  234.                 while((I1==0)&&((timeout1++)<500));
  235.           Delay10us();
  236.                 Delay10us();
  237.                 Delay10us();
  238.                 _nop_();//31us
  239.            buf=buf<<1;
  240.            if(I1==1)
  241.                  {
  242.                          buf=buf|0x01;
  243.                  }
  244.                  timeout1=0;
  245.                 while((I1==1)&&((timeout1++)<500));
  246.         }
  247.           return buf;
  248. }
  249. /*******DHT11读温湿度************/
  250. uchar ReadRH1(void)
  251. {
  252.         I1=0;
  253.   Delay1ms(20);//20ms
  254.         I1=1;
  255.         Delay10us();
  256.         Delay10us();
  257.         Delay10us();
  258.         Delay10us();
  259.         Delay10us();//50us
  260.         if(I1==0)
  261.         {
  262.                 timeout1=0;
  263.                 while((I1==0)&&((timeout1++)<500));
  264.                 timeout1=0;
  265.                 while((I1==1)&&((timeout1++)<500));
  266.                 RH_H1=ReadByte1();
  267.                 RH_L1=ReadByte1();
  268.                 T_H1=ReadByte1();
  269.                 T_L1=ReadByte1();
  270.                 Cheakdata1=ReadByte1();
  271.                 if(Cheakdata1==RH_H1+RH_L1+T_H1+T_L1)
  272.                 {return 1;}//成功
  273.                 else
  274.                 {return 0;}//失败
  275.         }
  276.         else
  277.                 return 0;//失败
  278. }


  279. /******1602写地址函数*********/
  280. void LCD1602_WRITE_ADRESS(uchar x,uchar y)
  281. {
  282.         if(y==0)
  283.          LCD1602_WRITE_COM_BUSY(0x80+x);
  284.         else
  285.          LCD1602_WRITE_COM_BUSY(0x80+0x40+x);
  286. }
  287. /*********1602显示*************/
  288. void LCD1602_DISP(uchar x,uchar y,uchar buf)
  289. {
  290.   LCD1602_WRITE_ADRESS(x,y);
  291.         LCD1602_WRITE_DATA_BUSY(buf);//显示数字
  292. }
  293. /*****主函数*****/
  294. void main(void)
  295. {
  296.         UART_init();
  297.         LCD1602_init();
  298.        
  299.    while(1)
  300.          {
  301.           
  302.            if(ReadRH()==1)
  303.            if(ReadRH1()==1)
  304.            if(RXFRMOK)
  305.           
  306.                  {
  307.                           P1=0xff;
  308.                          PM2_5=((TXBUF[0]+TXBUF[1]*256)/10);
  309.              PM10=((TXBUF[2]+TXBUF[3]*256)/10);  
  310.              RXFRMOK=0;
  311.                           
  312.                          if(RH_H>99) RH_H=0;
  313.                          if(T_H>50) T_H=0;
  314.                          if(RH_H1>99) RH_H1=0;
  315.                          if(T_H1>50) T_H1=0;
  316.                
  317.                          if(PM10>120) l1=0;                   //关窗
  318.                          else if(PM2_5>30) l1=0;            //关窗
  319.                          else if(T_H1<12||T_H1>32) l1=0;            //关窗
  320.                          else if(T_H<T_H1) l1=0;           //        关窗
  321.                          else  l2=0;   //开窗
  322.                          
  323.                                                                                                                              
  324.                        
  325.                          LCD1602_DISP(0,0,'T');
  326.                          LCD1602_DISP(1,0,'1');
  327.                          LCD1602_DISP(2,0,':');
  328.                          LCD1602_DISP(3,0,T_H/10+'0');
  329.                          LCD1602_DISP(4,0,T_H%10+'0');          
  330.                          LCD1602_DISP(5,0,0xdf);
  331.                          LCD1602_DISP(6,0,'C');
  332.                          
  333.                          LCD1602_DISP(8,0,'P');
  334.                          LCD1602_DISP(9,0,'2');
  335.                          LCD1602_DISP(10,0,'5');
  336.                          //LCD1602_DISP(11,0,PM2_5/100+'0');
  337.                          LCD1602_DISP(12,0,PM2_5/10%10+'0');
  338.                          LCD1602_DISP(13,0,PM2_5%10+'0');
  339.                          LCD1602_DISP(14,0,'m');
  340.                          LCD1602_DISP(15,0,'g');
  341.                          
  342.                          LCD1602_DISP(0,1,'T');
  343.                          LCD1602_DISP(1,1,'2');
  344.                          LCD1602_DISP(2,1,':');
  345.                          LCD1602_DISP(3,1,T_H1/10+'0');
  346.                          LCD1602_DISP(4,1,T_H1%10+'0');
  347.                          LCD1602_DISP(5,1,0xdf);
  348.                          LCD1602_DISP(6,1,'C');
  349.                          
  350.                          LCD1602_DISP(8,1,'P');                         
  351.                          LCD1602_DISP(9,1,'1');
  352.                          LCD1602_DISP(10,1,'0');
  353.                          LCD1602_DISP(11,1,PM10/100+'0');
  354.                          LCD1602_DISP(12,1,PM10/10%10+'0');
  355.                          LCD1602_DISP(13,1,PM10%10+'0');
  356.                          LCD1602_DISP(14,1,'m');
  357.                          LCD1602_DISP(15,1,'g');
  358.                                 
  359.                          
  360.                          
  361.                  }
  362.          }
  363. }       

复制代码

所有资料51hei提供下载:
dht11.doc (47.5 KB, 下载次数: 103)


分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏2 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:454812 发表于 2018-12-26 14:08 | 只看该作者
6666 正好需要
回复

使用道具 举报

板凳
ID:445069 发表于 2019-2-23 15:41 | 只看该作者
89c52直接用楼主的代码,为什么在主机发出开始信号后,始终得不到DHT11发出的低电平的输出呢?
回复

使用道具 举报

地板
ID:528893 发表于 2019-5-6 20:31 | 只看该作者
为什么1602上什么都不显示啊
回复

使用道具 举报

5#
ID:369443 发表于 2019-9-30 21:57 | 只看该作者
正好需要部分代码
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表