找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 8842|回复: 11
收起左侧

基于51单片机的DHT11温湿度控制系统仿真设计 实测可用

  [复制链接]
ID:135102 发表于 2017-7-1 21:23 | 显示全部楼层 |阅读模式
单片机驱动DHT11获取环境温湿度并在1602显示,同时可以调整温湿度的各自的上下限,有提示降温除湿功能。程序实测可用

原理图,Proteus仿真文件(需要8.5以上版本才能打开)都有:
0.png 0.png
单片机源程序如下:
  1. //http://www.51hei.com/bbs/dpj-51190-1.html
  2. #include <reg51.h>
  3. #include <intrins.h>
  4. #define uchar unsigned char
  5. #define uint unsigned int
  6. typedef unsigned char  U8;       /* defined for unsigned 8-bits integer variable    无符号8位整型变量  */
  7. typedef signed   char  S8;       /* defined for signed 8-bits integer variable    有符号8位整型变量  */
  8. typedef unsigned int   U16;      /* defined for unsigned 16-bits integer variable    无符号16位整型变量 */

  9. sbit speek  =P3^4;  //报警
  10. sbit hh     =P2^1;        //高灯
  11. sbit ll     =P2^2;        //高灯

  12. sbit LCD_RS =P1^3;
  13. sbit LCD_RW =P1^4;
  14. sbit LCD_EN =P1^5;
  15. //sbit LCD_RS =P2^4;
  16. //sbit LCD_RW =P2^5;
  17. //sbit LCD_EN =P2^6;

  18. sbit setup  =P1^6;  //  设置+
  19. sbit setdown=P1^7;  //  设置-
  20. sbit set    =P3^0;    //  设置

  21. sbit  P2_0  =P1^0;          //DHT11的DATE
  22. sbit  P2_1  =P3^1;          //串行总线---不用

  23. //----------------------------------------------//
  24. //----------------定义区--------------------//
  25. //----------------------------------------------//
  26. U8  U8FLAG;
  27. U8  U8count,U8temp;
  28. U8  U8T_data_H,U8T_data_L,U8RH_data_H,U8RH_data_L,U8checkdata;
  29. U8  U8T_data_H_temp,U8T_data_L_temp,U8RH_data_H_temp,U8RH_data_L_temp,U8checkdata_temp;
  30. U8  U8comdata;   
  31. U8  indata[5];
  32. U8  count, count_r=0;
  33. U16 U16temp1,U16temp2;
  34. uchar settem_h,settem_l,sethum_h,sethum_l,con=0;
  35. bit sethumbz_h=0,sethumbz_l=0,settembz_h=0,settembz_l=0,setkey;
  36. uchar i;
  37. bit BIAO;
  38. void Delay_1(U16 j)           //100us延时
  39. {   
  40. U8 i;
  41. for(;j>0;j--)
  42. {  
  43.   for(i=0;i<27;i++);         
  44. }
  45. }
  46. //void elay(unsigned int num)//延时函数
  47. //{
  48. //  while( --num );
  49. //}

  50. void  Delay_10us(void)  //进入函数3us
  51. {
  52. U8 i;             //1us
  53. i--;                   //1us
  54. i--;
  55. i--;
  56. i--;
  57. i--;
  58. i--;
  59. }


  60.         

  61. /********************************************************************/
  62. /*                                                                  */
  63. /*检查LCD忙状态                                                     */
  64. /*lcd_busy为1时,忙,等待。lcd-busy为0时,闲,可写指令与数据。       */
  65. /*                                                                  */
  66. /********************************************************************/

  67. bit lcd_busy()
  68. {                          
  69.     bit result;
  70.     LCD_RS = 0;
  71.     LCD_RW = 1;
  72.     LCD_EN = 1;
  73.     _nop_();
  74.     _nop_();
  75.     _nop_();
  76.     _nop_();
  77.     result = (bit)(P0&0x80);
  78.     LCD_EN = 0;
  79.     return result;
  80. }

  81. /********************************************************************/
  82. /*                                                                  */
  83. /*写指令数据到LCD                                                   */
  84. /*RS=L,RW=L,E=高脉冲,D0-D7=指令码。                              */
  85. /*                                                                  */
  86. /********************************************************************/

  87. void lcd_wcmd(uchar cmd)

  88. {                          
  89.    while(lcd_busy());
  90.     LCD_RS = 0;
  91.     LCD_RW = 0;
  92.     LCD_EN = 0;
  93.     _nop_();
  94.     _nop_();
  95.     P0 = cmd;
  96.     _nop_();
  97.     _nop_();
  98.     _nop_();
  99.     _nop_();
  100.     LCD_EN = 1;
  101.     _nop_();
  102.     _nop_();
  103.     _nop_();
  104.     _nop_();
  105.     LCD_EN = 0;  
  106. }

  107. /********************************************************************/
  108. /*                                                                  */
  109. /*写显示数据到LCD                                                   */
  110. /*RS=H,RW=L,E=高脉冲,D0-D7=数据。                                */
  111. /*                                                                  */
  112. /********************************************************************/

  113. void lcd_wdat(uchar dat)
  114. {                          
  115.    while(lcd_busy());
  116.     LCD_RS = 1;
  117.     LCD_RW = 0;
  118.     LCD_EN = 0;
  119.     P0 = dat;
  120.     _nop_();
  121.     _nop_();
  122.     _nop_();
  123.     _nop_();
  124.     LCD_EN = 1;
  125.     _nop_();
  126.     _nop_();
  127.     _nop_();
  128.     _nop_();
  129.     LCD_EN = 0;
  130. }

  131. /********************************************************************/
  132. /*                                                                  */
  133. /*  LCD初始化设定                                                   */
  134. /*                                                                  */
  135. /********************************************************************/

  136. void lcd_init()
  137. {                        
  138.     lcd_wcmd(0x38);      //16*2显示,5*7点阵,8位数据
  139.     Delay_1(5);
  140.     lcd_wcmd(0x38);         
  141.     Delay_1(5);
  142.     lcd_wcmd(0x38);         
  143.     Delay_1(5);

  144.     lcd_wcmd(0x0c);      //显示开,关光标
  145.     Delay_1(5);
  146.     lcd_wcmd(0x06);      //移动光标
  147.     Delay_1(5);
  148.     lcd_wcmd(0x01);      //清除LCD的显示内容
  149.     Delay_1(5);
  150. }

  151. /********************************************************************/
  152. /*                                                                  */
  153. /*  设定显示位置                                                    */
  154. /*                                                                  */
  155. /********************************************************************/

  156. void lcd_pos(uchar pos)
  157. {                          
  158.   lcd_wcmd(pos | 0x80);  //数据指针=80+地址变量
  159. }

  160. void LCD1602PutStr(char* s)
  161. {
  162.         uchar i = 0;
  163.         while (*(i + s))
  164.                 {
  165.                 lcd_wdat(*(i + s));
  166.                                 Delay_1(200);
  167.                 i++;
  168.         }
  169. }



  170. void COM(void)                 //串行读一个字节数据
  171. {
  172. U8 i;
  173. for(i=0;i<8;i++)   
  174. {
  175.   U8FLAG=2;
  176.   while((!P2_0)&&U8FLAG++);        //自加254次 默认执行下面程序 50us低电平结束判断
  177.   Delay_10us();
  178.   Delay_10us();
  179.   Delay_10us();         
  180.   U8temp=0;
  181.   if(P2_0)U8temp=1;
  182.   U8FLAG=2;
  183.   while((P2_0)&&U8FLAG++);
  184.   
  185.   if(U8FLAG==1)break;  //屏蔽
  186.   U8comdata<<=1;
  187.   U8comdata|=U8temp;      
  188. }

  189. }

  190. //--------------------------------
  191. //-----湿度读取子程序 ------------
  192. //--------------------------------
  193. //----以下变量均为全局变量--------
  194. //----温度高8位== U8T_data_H------
  195. //----温度低8位== U8T_data_L------
  196. //----湿度高8位== U8RH_data_H-----
  197. //----湿度低8位== U8RH_data_L-----
  198. //----校验 8位 == U8checkdata-----
  199. //----调用相关子程序如下----------
  200. //---- Delay();, Delay_10us();,COM();
  201. //--------------------------------

  202. void RH(void)
  203. {  TR0=0;
  204.   //主机拉低18ms
  205.    P2_0=0;
  206.    Delay_1(180);
  207.    P2_0=1;
  208. //总线由上拉电阻拉高 主机延时20us
  209.    Delay_10us();
  210.    Delay_10us();
  211.    Delay_10us();
  212.    Delay_10us();
  213.    P2_0=1;  
  214.    //主机设为输入 判断从机响应信号
  215.    if(!P2_0) //判断从机是否有低电平响应信号 如不响应则不读数据,响应则向下运行     
  216.     {        //speek=0;
  217.             U8FLAG=2;
  218.             while((!P2_0)&&U8FLAG++);
  219.             U8FLAG=2;
  220.             while((P2_0)&&U8FLAG++);
  221.             //数据接收状态   
  222.             COM();
  223.             U8RH_data_H_temp=U8comdata;
  224.             COM();
  225.             U8RH_data_L_temp=U8comdata;
  226.             COM();
  227.             U8T_data_H_temp=U8comdata;
  228.             COM();
  229.             U8T_data_L_temp=U8comdata;
  230.             COM();
  231.             U8checkdata_temp=U8comdata;
  232.             P2_0=1;
  233.             //数据校验
  234.          
  235.             U8temp=(U8T_data_H_temp+U8T_data_L_temp+U8RH_data_H_temp+U8RH_data_L_temp);
  236.             if(U8temp==U8checkdata_temp)
  237.             {
  238.                U8RH_data_H=U8RH_data_H_temp;
  239.                U8RH_data_L=U8RH_data_L_temp;
  240.                U8T_data_H=U8T_data_H_temp;
  241.                U8T_data_L=U8T_data_L_temp;
  242.                U8checkdata=U8checkdata_temp;
  243.                   
  244.             }
  245.                 TR0=1;
  246.    }

  247. }

  248. void Disp_Temperature()//显示温度
  249. {
  250. //unsigned char  n=0;
  251. //  display[4]=temp_data[0]&0x0f;
  252. //  display[0]=ditab[display[4]];     //查表得小数位的值
  253. //  display[4]=((temp_data[0]&0xf0)>>4)|((temp_data[1]&0x0f)<<4);
  254.                 Delay_1(200);
  255.         lcd_pos(0x04);
  256.         lcd_wdat('0'+U8RH_data_H/10);  /* 显示湿度 */
  257.                 Delay_1(200);
  258.         lcd_wdat('0'+U8RH_data_H%10);  

  259.                  Delay_1(200);
  260.         lcd_pos(0x44);
  261.         lcd_wdat('0'+U8T_data_H/10);  /* 显示温度*/
  262.                  Delay_1(200);
  263.         lcd_wdat('0'+U8T_data_H%10);

  264.                 Delay_1(200);
  265.         lcd_pos(9);
  266.         lcd_wdat('0' + sethum_h / 10);
  267.                 Delay_1(200);
  268.         lcd_wdat('0' + sethum_h % 10); /* 显示湿度上限 */
  269.                 Delay_1(200);
  270.         lcd_pos(13);
  271.         lcd_wdat('0' + sethum_l / 10);
  272.                 Delay_1(200);
  273.         lcd_wdat('0' + sethum_l % 10); /* 显示湿度下限 */               
  274.         
  275.                 Delay_1(200);
  276.         lcd_pos(0x49);
  277.         lcd_wdat('0' + settem_h / 10);
  278.                 Delay_1(200);
  279.         lcd_wdat('0' + settem_h % 10); /* 显示温度上限 */

  280.                 Delay_1(200);
  281.         lcd_pos(0x4d);
  282.         lcd_wdat('0' + settem_l / 10);
  283.          Delay_1(200);
  284.         lcd_wdat('0' + settem_l % 10); /* 显示温度下限 */
  285.         

  286.            if ((settembz_h==0)&&(settembz_l)&&(sethumbz_h)&&(sethumbz_l))
  287.            {
  288.                      lcd_pos(0x4f);         //消湿度下限的箭头
  289.          lcd_wdat(' ');
  290.                  Delay_1(10);
  291.          lcd_pos(0x0f);
  292.          lcd_wdat(' ');
  293.            
  294.            }

  295.            if (settembz_h)
  296.         {
  297.          lcd_pos(0x4f);         //消湿度下限的箭头
  298.          
  299. ……………………

  300. …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码

所有资料51hei提供下载:
基于51单片机的DHT11温湿度控制系统.rar (2.05 MB, 下载次数: 343)

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

ID:698121 发表于 2020-3-2 17:54 | 显示全部楼层
为什么仿真的时候液晶屏不显示温湿度呢
回复

使用道具 举报

ID:135102 发表于 2017-7-1 21:25 | 显示全部楼层
stc12c5a60s2用不了,实测AT89C52RC可用,晶振11.0592MHZ
回复

使用道具 举报

ID:88606 发表于 2017-8-23 09:21 | 显示全部楼层
看楼下的 说明,刚好手头有stc12c5a60s2,来试试否真的不能用!
回复

使用道具 举报

ID:101093 发表于 2017-8-23 11:56 | 显示全部楼层
回头试试,看能不能用!
回复

使用道具 举报

ID:235332 发表于 2019-10-16 16:01 | 显示全部楼层
代码和仿真图的管脚不一样
回复

使用道具 举报

ID:634994 发表于 2019-11-3 20:57 | 显示全部楼层
感谢 太实用了
回复

使用道具 举报

ID:505668 发表于 2020-4-20 19:31 | 显示全部楼层
仿真不了。。。
回复

使用道具 举报

ID:773644 发表于 2020-6-9 09:59 来自手机 | 显示全部楼层
为什么什么8.6都打不开他的仿真
回复

使用道具 举报

ID:557673 发表于 2020-7-27 18:21 | 显示全部楼层
仿真运行无显示啊
回复

使用道具 举报

ID:510607 发表于 2020-10-6 00:16 | 显示全部楼层
没有显示呀
回复

使用道具 举报

ID:109079 发表于 2020-10-6 21:39 | 显示全部楼层
本帖最后由 清风碧雪 于 2020-10-6 22:17 编辑

DHT11这种温湿度传感器前些日子玩过,在单位仓库里发现的,单位一些配电柜里用这玩意。清库存的时候弄了几个,这玩意只能显示两位整数而且个体间差异太大,代换性不好,湿度就更离谱了。传一个采用12232液晶屏显示的程序。

12232C.rar

55.25 KB, 下载次数: 11, 下载积分: 黑币 -5

回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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