找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 4117|回复: 3
收起左侧

stc单片机和DHT11温湿度传感器组成报警系统

[复制链接]
ID:124669 发表于 2016-6-2 13:34 | 显示全部楼层 |阅读模式
图3.2 为DHT11传感器实物图,其性能指标和特性如下:
  (1)工作电压范围:3.5V-5.5V;
  (2)工作电流 :平均0.5mA;
  (3)湿度测量范围:20-90%RH ;
  (4)温度测量范围:0-50℃ ;
  (5)湿度分辨率 :1%RH 8位;
  (6)温度分辨率 :1℃ 8位;
  (7)采样周期 :1S ;
  (8)单总线结构 ;
9TTL兼容(5V

0.png

  1. #include <reg51.h>
  2. #include <intrins.h>
  3. #define uchar unsigned char
  4. #define uint unsigned int
  5. typedef unsigned char  U8;       /* defined for unsigned 8-bits integer variable    无符号8位整型变量  */
  6. typedef signed   char  S8;       /* defined for signed 8-bits integer variable    有符号8位整型变量  */
  7. typedef unsigned int   U16;      /* defined for unsigned 16-bits integer variable    无符号16位整型变量 */

  8. sbit set=P2^2 ;
  9. //  设置
  10. sbit setup=P2^1 ;
  11. //  设置+
  12. sbit setdown=P2^0 ;
  13. //  设置-
  14. sbit speek=P1^0;
  15. sbit hh=P1^1;
  16. sbit ll=P1^2;
  17. sbit LCD_RS=P2^7;
  18. sbit LCD_RW=P2^6;
  19. sbit LCD_EN=P2^5;
  20. sbit  P2_0  = P3^7 ;
  21. sbit  P2_1  = P3^1 ;

  22. //----------------------------------------------//
  23. //----------------定义区--------------------//
  24. //----------------------------------------------//
  25. U8  U8FLAG;
  26. U8  U8count,U8temp;
  27. U8  U8T_data_H,U8T_data_L,U8RH_data_H,U8RH_data_L,U8checkdata;
  28. U8  U8T_data_H_temp,U8T_data_L_temp,U8RH_data_H_temp,U8RH_data_L_temp,U8checkdata_temp;
  29. U8  U8comdata;   
  30. U8  indata[5];
  31. U8  count, count_r=0;
  32. U16 U16temp1,U16temp2;
  33. uchar settem_h,settem_l,sethum_h,sethum_l,con=0;
  34. bit sethumbz_h=0,sethumbz_l=0,settembz_h=0,settembz_l=0,setkey;
  35. uchar i;

  36. void Delay_1(U16 j)
  37. {   
  38. U8 i;
  39. for(;j>0;j--)
  40. {  
  41.   for(i=0;i<127;i++);
  42. }
  43. }
  44. //void elay(unsigned int num)//延时函数
  45. //{
  46. //  while( --num );
  47. //}
  48. void  Delay_10us(void)
  49. {
  50. U8 i;
  51. i--;
  52. i--;
  53. i--;
  54. i--;
  55. i--;
  56. i--;
  57. }


  58.        

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

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

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

  85. void lcd_wcmd(uchar cmd)

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

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

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

  129. /********************************************************************/
  130. /*                                                                  */
  131. /*  LCD初始化设定                                                   */
  132. /*                                                                  */
  133. /********************************************************************/

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

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

  149. /********************************************************************/
  150. /*                                                                  */
  151. /*  设定显示位置                                                    */
  152. /*                                                                  */
  153. /********************************************************************/

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

  158. void LCD1602PutStr(char* s)
  159. {
  160.         uchar i = 0;
  161.         while (*(i + s)) {
  162.                 lcd_wdat(*(i + s));
  163.                 i++;
  164.         }
  165. }


  166. //串行总线  
  167. void COM(void)
  168. {

  169. U8 i;
  170. for(i=0;i<8;i++)   
  171. {

  172.   U8FLAG=2;
  173.   //----------------------
  174.   P2_1=0 ;  //T
  175.   P2_1=1 ;  //T
  176.   //----------------------
  177.   
  178.   while((!P2_0)&&U8FLAG++);
  179.   Delay_10us();
  180.   Delay_10us();
  181.   // Delay_10us();
  182.   U8temp=0;
  183.   if(P2_0)U8temp=1;
  184.   U8FLAG=2;
  185.   while((P2_0)&&U8FLAG++);
  186.   
  187.   //----------------------
  188.   P2_1=0 ;  //T
  189.   P2_1=1 ;  //T
  190.   //----------------------
  191.   //超时则跳出for循环   
  192.   if(U8FLAG==1)break;
  193.   //判断数据位是0还是1  
  194.   
  195.   // 如果高电平高过预定0高电平值则数据位为 1
  196.   
  197.   U8comdata<<=1;
  198.   U8comdata|=U8temp;        //0
  199. }//rof

  200. }

  201. //--------------------------------
  202. //-----湿度读取子程序 ------------
  203. //--------------------------------
  204. //----以下变量均为全局变量--------
  205. //----温度高8位== U8T_data_H------
  206. //----温度低8位== U8T_data_L------
  207. //----湿度高8位== U8RH_data_H-----
  208. //----湿度低8位== U8RH_data_L-----
  209. //----校验 8位 == U8checkdata-----
  210. //----调用相关子程序如下----------
  211. //---- Delay();, Delay_10us();,COM();
  212. //--------------------------------

  213. void RH(void)
  214. {
  215.   //主机拉低18ms
  216.    P2_0=0;
  217.    Delay_1(180);
  218.    P2_0=1;
  219. //总线由上拉电阻拉高 主机延时20us
  220.    Delay_10us();
  221.    Delay_10us();
  222.    Delay_10us();
  223.    Delay_10us();
  224. //主机设为输入 判断从机响应信号
  225.    P2_0=1;
  226. //判断从机是否有低电平响应信号 如不响应则跳出,响应则向下运行   
  227.    if(!P2_0)   //T !   
  228.     {
  229.     U8FLAG=2;////////////////////////////////////////////////////
  230.   //判断从机是否发出 80us 的低电平响应信号是否结束  
  231.     while((!P2_0)&&U8FLAG++);
  232.     U8FLAG=2;
  233.   //判断从机是否发出 80us 的高电平,如发出则进入数据接收状态
  234.     while((P2_0)&&U8FLAG++);
  235.   //数据接收状态   
  236.     COM();
  237.     U8RH_data_H_temp=U8comdata;
  238.     COM();
  239.     U8RH_data_L_temp=U8comdata;
  240.     COM();
  241.     U8T_data_H_temp=U8comdata;
  242.     COM();
  243.     U8T_data_L_temp=U8comdata;
  244.     COM();
  245.     U8checkdata_temp=U8comdata;
  246.     P2_0=1;
  247.   //数据校验
  248.   
  249.     U8temp=(U8T_data_H_temp+U8T_data_L_temp+U8RH_data_H_temp+U8RH_data_L_temp);
  250.     if(U8temp==U8checkdata_temp)
  251.     {
  252.        U8RH_data_H=U8RH_data_H_temp;
  253.        U8RH_data_L=U8RH_data_L_temp;
  254.     U8T_data_H=U8T_data_H_temp;
  255.        U8T_data_L=U8T_data_L_temp;
  256.        U8checkdata=U8checkdata_temp;
  257.     }//fi
  258.    }//fi

  259. }

  260. Disp_Temperature()//显示温度
  261. {
  262. //unsigned char  n=0;

  263. //  display[4]=temp_data[0]&0x0f;
  264. //  display[0]=ditab[display[4]];     //查表得小数位的值
  265.   
  266. //  display[4]=((temp_data[0]&0xf0)>>4)|((temp_data[1]&0x0f)<<4);
  267.         lcd_pos(0x04);
  268.         lcd_wdat('0'+U8RH_data_H/10);
  269.         lcd_wdat('0'+U8RH_data_H%10);
  270.         lcd_pos(0x44);
  271.         lcd_wdat('0'+U8T_data_H/10);
  272.         lcd_wdat('0'+U8T_data_H%10);

  273.         lcd_pos(9);
  274.         lcd_wdat('0' + sethum_h / 10);
  275.         lcd_wdat('0' + sethum_h % 10); /* 显示湿度上限 */
  276.         lcd_pos(13);
  277.         lcd_wdat('0' + sethum_l / 10);
  278.         lcd_wdat('0' + sethum_l % 10); /* 显示湿度下限 */               
  279.        
  280.         lcd_pos(0x49);
  281.         lcd_wdat('0' + settem_h / 10);
  282.         lcd_wdat('0' + settem_h % 10); /* 显示温度上限 */
  283.         lcd_pos(0x4d);
  284.         lcd_wdat('0' + settem_l / 10);
  285.         lcd_wdat('0' + settem_l % 10); /* 显示温度下限 */
  286.        
  287.                   if (settembz_h)
  288.                 {
  289.                         lcd_pos(0x4f);
  290.                         lcd_wdat(' ');
  291.                         lcd_pos(0x0f);
  292.                         lcd_wdat(' ');
  293.                         lcd_pos(0x0b);
  294.                         lcd_wdat(' ');
  295.                         lcd_pos(0x4b);
  296.                         lcd_wdat(127);
  297.         }
  298.                   if (settembz_l)               
  299.                 {
  300.                         lcd_pos(0x0f);
  301.                         lcd_wdat(' ');
  302.                         lcd_pos(0x0b);
  303.                         lcd_wdat(' ');
  304.                         lcd_pos(0x4b);
  305.                         lcd_wdat(' ');
  306.                         lcd_pos(0x4f);
  307.                         lcd_wdat(127);       
  308.                 }
  309.                 if (sethumbz_h)
  310.                 {
  311.                         lcd_pos(0x0f);
  312.                         lcd_wdat(' ');
  313.                         lcd_pos(0x4b);
  314.                         lcd_wdat(' ');
  315.                         lcd_pos(0x4f);
  316.                         lcd_wdat(' ');
  317.                         lcd_pos(0x0b);
  318.                         lcd_wdat(127);
  319.                
  320.                 }
  321.             if (sethumbz_l)
  322.                 {
  323.                         lcd_pos(0x4f);
  324.                         lcd_wdat(' ');
  325.                         lcd_pos(0x4b);
  326.                         lcd_wdat(' ');
  327.                         lcd_pos(0x0b);
  328.                         lcd_wdat(' ');
  329.                         lcd_pos(0x0f);
  330.                         lcd_wdat(127);
  331.             }

  332. }
  333. void doing()
  334. {
  335.     uchar xianzhi_mi ,shiduzhi;
  336.     xianzhi_mi=U8T_data_H ;
  337.         shiduzhi=U8RH_data_H;
  338.     if((xianzhi_mi<settem_h)&(xianzhi_mi>settem_l)&(shiduzhi<sethum_h)&(shiduzhi>sethum_l))
  339.     {
  340.         ll=1 ;
  341.         hh=1 ;
  342.         speek=1 ;
  343.     }
  344.     if((xianzhi_mi>settem_h)||(shiduzhi>sethum_h))
  345.     {
  346.         hh=0 ;
  347.         ll=1;
  348.         speek=0;
  349.     }
  350.     if((xianzhi_mi<settem_l)||(shiduzhi<sethum_l))
  351.     {
  352.         hh=1 ;
  353.         ll=0 ;
  354.         speek=0 ;
  355.     }
  356. }

  357. void key()
  358. {
  359.         if(set==0)
  360.         {
  361.                 Delay_1(2);
  362.                 if(set==0)
  363.                 {
  364.                         while(!set);
  365.                         con++;
  366.                         setkey=1;
  367.                        
  368.                 }
  369.                 switch(con)
  370.                 {
  371.                         case 1:sethumbz_h=1;sethumbz_l=0;;break;
  372.                         case 2:sethumbz_h=0;sethumbz_l=1;break;
  373.                         case 3:settembz_h=1;settembz_l=0;sethumbz_l=0;break;
  374.                         case 4:settembz_h=0;settembz_l=1;break;
  375.                         default:sethumbz_h=0;sethumbz_l=0;settembz_h=0;settembz_l=0;con=0;setkey=0;
  376.                 }
  377.         }
  378.         if((setup==0)&setkey)
  379.         {
  380.                 Delay_1(5);
  381.                 while(!setup);
  382.                 if(sethumbz_h==1)
  383.                 {
  384.                         if(sethum_h<=99)
  385.                         sethum_h++;

  386.                 }
  387.                 if(settembz_h==1)
  388.                 {
  389.                         if(settem_h<=99)
  390.                         settem_h++;

  391.                 }
  392.                 if(sethumbz_l==1)
  393.                 {
  394.                         if((sethum_l<sethum_h)&(sethum_l<=99))
  395.                         sethum_l++;
  396.                 }
  397.                 if(settembz_l==1)
  398.                 {
  399.                         if((settem_l<settem_h)&(settem_l<=99))
  400.                         settem_l++;
  401.                 }
  402.         }
  403.         if((setdown==0)&setkey)
  404.         {
  405.                 Delay_1(5);
  406.                 while(!setdown);
  407.                 if(sethumbz_h==1)
  408.                 {
  409.                         if((sethum_h>sethum_l)&(sethum_h>=1))
  410.                         sethum_h--;

  411.                 }
  412.                 if(settembz_h==1)

  413.                 {
  414.                         if((settem_h>settem_l)&(settem_h>=1))
  415.                         settem_h--;

  416.                 }
  417.                 if(settembz_l==1)
  418.                 {
  419.                         if(settem_l>=1)
  420.                         settem_l--;
  421.                 }
  422.                 if(sethumbz_l==1)
  423.                 {
  424.                         if(sethum_l>=1)
  425.                         sethum_l--;
  426.                 }
  427.         }

  428. }


  429. void init_time()
  430. {
  431.         TMOD=0x01 ;
  432.     TH0=(65535-5000)/256;
  433.     TL0=(65535-5000)%256 ;
  434.     TR0=1 ;
  435.     EA=1 ;
  436.     ET0=1 ;
  437. }
  438. void main(void)
  439. {
  440.         P1=0xff;
  441.     settem_h=30 ;
  442.     //设置高温
  443.     settem_l=0 ;
  444.     //设置低温
  445.         sethum_h=70;//湿度上线报警值
  446.         sethum_l=0;//湿度下限报警值
  447.         lcd_init();
  448.         lcd_pos(0);
  449.         LCD1602PutStr("hum:"); /* 第一行显示湿度 */
  450.         lcd_pos(7);
  451.         LCD1602PutStr("H "); /* 上限值 */
  452.         lcd_pos(12);
  453.         LCD1602PutStr("L");
  454.         lcd_pos(0x40);
  455.         LCD1602PutStr("tem:"); /*第二行显示温度*/
  456.         lcd_pos(0x47);
  457.         LCD1602PutStr("H "); /*  下限值 */
  458.         lcd_pos(0x4c);
  459.         LCD1602PutStr("L");
  460.         init_time();
  461.   while(1)
  462.   {
  463.                
  464.     Disp_Temperature();
  465.         key();
  466.         doing();
  467.   }
  468. }

  469. time0()   interrupt 1
  470. {
  471.        
  472.         i++;
  473.         if(i==20)
  474.         {
  475.             RH();
  476.                 i=0;
  477.         }
  478.         TH0=(65535-5000)/256;
  479.     TL0=(65535-5000)%256;
  480. }
复制代码


DHT11原理图.docx

42.15 KB, 下载次数: 26, 下载积分: 黑币 -5

DHT-11.docx

17.01 KB, 下载次数: 28, 下载积分: 黑币 -5

评分

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

查看全部评分

回复

使用道具 举报

ID:244745 发表于 2017-11-1 11:28 | 显示全部楼层
学习了
回复

使用道具 举报

ID:244589 发表于 2017-12-1 08:35 | 显示全部楼层
楼主,没有看到温度呢,只用湿度传感器就可以测温湿度吗
回复

使用道具 举报

ID:270891 发表于 2018-1-3 17:26 | 显示全部楼层
楼主,学习了你的代码,但是我这边温湿度一直显示0是为什么
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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