找回密码
 立即注册

QQ登录

只需一步,快速开始

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

DHT11按键调节温湿度+YL69土壤湿度报警

  [复制链接]
跳转到指定楼层
楼主
ID:222946 发表于 2017-7-28 10:39 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
DHT11按键控制+土壤湿度报警

单片机源程序如下:
  1. #include<reg52.h>
  2. #include "intrins.h"
  3. typedef unsigned char uint8;
  4. typedef unsigned int uint16;
  5. sbit rs=P2^6;     // 数据命令选择
  6. sbit rw=P2^5;     //读写选择
  7. sbit e=P2^7;      //使能

  8. sbit k1=P3^3; //模式
  9. sbit k2=P2^1; //加
  10. sbit k3=P2^2; //减
  11. sbit bee=P1^5;//蜂鸣器

  12. sbit DO=P3^1;
  13. sbit DHT11_DQ_OUT=P3^2;
  14. sbit led1=P1^0;
  15. sbit led2=P1^1;
  16. sbit led3=P1^2;

  17. sbit dq=P2^0;

  18. uint8 date;
  19. uint8 mode=0,xian;
  20. char temph=28,templ=20;
  21. char humih=80,humil=20;
  22. uint8 temp,humi;
  23. uint8 flag;      //设定报警标志
  24. uint8 code num[10]="0123456789";

  25. uint8 code str1[]="Temp:";  //温度
  26. uint8 code str2[]="Humi:";  //湿度
  27. uint8 code str3[]="Error";  
  28. uint8 code str4[]="Success    ";
  29. uint8 code str5[]="%RH";
  30. uint8 code str6[]="TempH:";      //设定温度上限显示
  31. uint8 code str7[]="TempL:";      //设定温度下限显示
  32. uint8 code str8[]="HumiH:";       //设定湿度上限显示
  33. uint8 code str9[]="HumiL:";       //设定湿度下限显示


  34. void delay(uint16 i)
  35. {
  36.     while(i--);
  37. }

  38. void delay_ms(uint16 i)
  39. {
  40.     while(i--)
  41.         delay(90);
  42. }
  43. void delay1(uint16 z)
  44. {                                                                                               
  45.     uint16 i,j;
  46.     for(i=z;i>0;i--)
  47.         for(j=110;j>0;j--);
  48. }

  49. void wrc(uint8 c)     //写命令
  50. {
  51.     delay(1000);
  52.     rs=0;
  53.     rw=0;
  54.     e=0;
  55.     P0=c;
  56.     e=1;
  57.     delay(10);
  58.     e=0;
  59. }
  60. void wrd(uint8 dat)      //写数据
  61. {
  62.     delay(1000);
  63.     rs=1;
  64.     rw=0;
  65.     e=0;
  66.     P0=dat;
  67.     e=1;
  68.     delay(10);
  69.     e=0;
  70.     rs=0;
  71. }
  72. void lcd_init()       // LCD1602初始化
  73. {
  74.     delay(1000);
  75.     wrc(0x38);
  76.     wrc(0x38);     //功能设置命令,选择8位总线,双行显示  5*7点阵字符
  77.     wrc(0x38);
  78.     wrc(0x06);    //光标和显示模式设置  光标右移  整屏不移动
  79.     wrc(0x0c);    //显示开关控制  开显示  无光标 光标不闪烁
  80.     wrc(0x01);    //清零指令  固定的
  81. }
  82. //复位DHT11
  83. void DHT11_Rst()      
  84. {                 
  85.     DHT11_DQ_OUT=0;     //拉低DQ
  86.     delay_ms(20);        //拉低至少18ms
  87.     DHT11_DQ_OUT=1;     //DQ=1
  88.     delay(3);         //主机拉高20~40us
  89. }

  90. //等待DHT11的回应
  91. //返回1:未检测到DHT11的存在
  92. //返回0:存在
  93. uint8 DHT11_Check()        
  94. {   
  95.     uint8 retry=0;     
  96.     while (DHT11_DQ_OUT&&retry<100)//DHT11会拉低40~50us
  97.     {
  98.         retry++;
  99.         _nop_();
  100.     };     
  101.     if(retry>=100)return 1;
  102.     else retry=0;
  103.     while (!DHT11_DQ_OUT&&retry<100)//DHT11拉低后会再次拉高40~50us
  104.     {
  105.         retry++;
  106.         _nop_();
  107.     };
  108.     if(retry>=100)return 1;        
  109.     return 0;
  110. }


  111. //DHT11初始化
  112. //返回0:初始化成功,1:失败
  113. uint8 DHT11_Init()
  114. {
  115.     DHT11_Rst();      
  116.     return DHT11_Check();   
  117. }


  118. //从DHT11读取一个位
  119. //返回值:1/0
  120. uint8 DHT11_Read_Bit(void)              
  121. {
  122.      uint8 retry=0;
  123.     while(DHT11_DQ_OUT&&retry<100)//等待变为低电平 12-14us 开始
  124.     {
  125.         retry++;
  126.         _nop_();
  127.     }
  128.     retry=0;
  129.     while((!DHT11_DQ_OUT)&&retry<100)//等待变高电平     26-28us表示0,116-118us表示1
  130.     {
  131.         retry++;
  132.         _nop_();
  133.     }
  134.     delay(1);//等待40us
  135.     if(DHT11_DQ_OUT)return 1;
  136.     else return 0;           
  137. }

  138. //从DHT11读取一个字节
  139. //返回值:读到的数据
  140. uint8 DHT11_Read_Byte(void)   
  141. {        
  142.     uint8 i,dat=0;
  143.     for (i=0;i<8;i++)
  144.     {
  145.            dat<<=1;
  146.         dat|=DHT11_Read_Bit();
  147.     }                           
  148.     return dat;
  149. }

  150. //从DHT11读取一次数据
  151. //temp:温度值(范围:0~50°)
  152. //humi:湿度值(范围:20%~90%)
  153. //返回值:0,正常;1,读取失败
  154. uint8 DHT11_Read_Data(uint8 *temp,uint8 *humi)   
  155. {        
  156.      uint8 buf[5];
  157.     uint8 i;
  158.     DHT11_Rst();
  159.     if(DHT11_Check()==0)
  160.     {
  161.         for(i=0;i<5;i++)//读取40位数据
  162.         {
  163.             buf[i]=DHT11_Read_Byte();
  164.         }
  165.         if((buf[0]+buf[1]+buf[2]+buf[3])==buf[4])
  166.         {
  167.             *humi=buf[0];
  168.             *temp=buf[2];
  169.         }
  170.         
  171.     }else return 1;
  172.     return 0;        
  173. }


  174. void key_pros()  //按键处理函数
  175. {
  176.     if(k1==0)
  177.     {
  178.         delay(1000);
  179.         if(k1==0)
  180.         {
  181.             mode++;
  182.             if(mode==5)mode=0;
  183.             wrc(0x01);
  184.         }
  185.         while(!k1);
  186.     }
  187.     if(mode==1)          //对温度上限设定
  188.     {
  189.         if(k2==0)          //加
  190.         {
  191.             delay(1000);
  192.             if(k2==0)
  193.             {
  194.                 temph++;
  195.                 if(temph>=80)temph=80;
  196.             }
  197.             while(!k2);
  198.         }
  199.         if(k3==0)       //减
  200.         {
  201.             delay(1000);
  202.             if(k3==0)
  203.             {
  204.                 temph--;
  205.                 if(temph<=0)temph=0;
  206.             }
  207.             while(!k3);
  208.         }
  209.     }
  210.     if(mode==2)          //对温度下限设定
  211.     {
  212.         if(k2==0)          //加
  213.         {
  214.             delay(1000);
  215.             if(k2==0)
  216.             {
  217.                 templ++;
  218.                 if(templ>=80)templ=80;
  219.             }
  220.             while(!k2);
  221.         }
  222.         if(k3==0)       //减
  223.         {
  224.             delay(1000);
  225.             if(k3==0)
  226.             {
  227.                 templ--;
  228.                 if(templ<=0)templ=0;
  229.             }
  230.             while(!k3);
  231.         }
  232.     }
  233.     if(mode==3)          //对湿度上限设定
  234.     {
  235.         if(k2==0)          //加
  236.         {
  237.             delay(1000);
  238.             if(k2==0)
  239.             {
  240.                 humih++;
  241.                 if(humih>=80)humih=80;
  242.             }
  243.             while(!k2);
  244.         }
  245.         if(k3==0)       //减
  246.         {
  247.             delay(1000);
  248.             if(k3==0)
  249.             {
  250.                 humih--;
  251.                 if(humih<=0)humih=0;
  252.             }
  253.             while(!k3);
  254.         }
  255.     }
  256.     if(mode==4)          //对湿度下限设定
  257.     {
  258.         if(k2==0)          //加
  259.         {
  260.             delay(1000);
  261.             if(k2==0)
  262.             {
  263.                 humil++;
  264.                 if(humil>=80)humil=80;
  265.             }
  266.             while(!k2);
  267.         }
  268.         if(k3==0)       //减
  269.         {
  270.             delay(1000);
  271.             if(k3==0)
  272.             {
  273.                 humil--;
  274.                 if(humil<=0)humil=0;
  275.             }
  276.             while(!k3);
  277.         }
  278.     }
  279. }

  280. void lcd_init_display()       //LCD初始化显示
  281. {
  282.     uint8 i;
  283.     for(i=0;i<5;i++)
  284.     {
  285.         wrc(0x80+i);
  286.         wrd(str1[i]);   
  287.     }

  288.     for(i=0;i<5;i++)
  289.     {
  290.         wrc(0xc0+i);
  291.         wrd(str2[i]);   
  292.     }
  293. }

  294. void data_pros()    //数据处理函数
  295. {
  296.     uint8 i;         
  297.     uint8 temp_buf[2],humi_buf[2];
  298.     uint8 temphbuf[2],templbuf[2],humihbuf[2],humilbuf[2];


  299.     DHT11_Read_Data(&temp,&humi);
  300.     temp_buf[0]=temp/10+0x30;   
  301.     temp_buf[1]=temp%10+0x30;

  302.     humi_buf[0]=humi/10+0x30;   
  303.     humi_buf[1]=humi%10+0x30;
  304.    


  305.     temphbuf[0]=temph/10+0x30;
  306.     temphbuf[1]=temph%10+0x30;
  307.     templbuf[0]=templ/10+0x30;
  308.     templbuf[1]=templ%10+0x30;

  309.     humihbuf[0]=humih/10+0x30;
  310.     humihbuf[1]=humih%10+0x30;
  311.     humilbuf[0]=humil/10+0x30;
  312.     humilbuf[1]=humil%10+0x30;

  313.     if(mode==0)
  314.     {
  315.         lcd_init_display();
  316.         wrc(0x85);
  317.         wrd(num[temp/10]);
  318.         wrd(num[temp%10]);
  319.         wrd(0xdf);
  320.         wrd('C');
  321.    
  322.         for(i=0;i<2;i++)
  323.         {
  324.             wrc(0Xc5+i);
  325.             wrd(humi_buf[i]);         
  326.         }   
  327.         for(i=0;i<3;i++)
  328.         {
  329.             wrc(0Xc7+i);
  330.             wrd(str5[i]);         
  331.         }   
  332.     }
  333.     if(mode==1)              //温度上限显示
  334.     {
  335.         wrc(0x80);
  336.         for(i=0;i<6;i++)
  337.         {
  338.             wrd(str6[i]);         
  339.         }
  340.         wrd(temphbuf[0]);
  341.         wrd(temphbuf[1]);            
  342.     }
  343.     if(mode==2)              //温度下限显示
  344.     {
  345.         wrc(0x80);
  346.         for(i=0;i<6;i++)
  347.         {
  348.             wrd(str7[i]);         
  349.         }
  350.         wrd(templbuf[0]);
  351.         wrd(templbuf[1]);            
  352.     }
  353.     if(mode==3)              //湿度上限显示
  354.     {
  355.         wrc(0x80);
  356.         for(i=0;i<6;i++)
  357.         {
  358.             wrd(str8[i]);         
  359.         }
  360.         wrd(humihbuf[0]);
  361.         wrd(humihbuf[1]);            
  362.     }
  363.     if(mode==4)              //湿度下限显示
  364.     {
  365.         wrc(0x80);
  366.         for(i=0;i<6;i++)
  367.         {
  368.             wrd(str9[i]);         
  369.         }
  370.         wrd(humilbuf[0]);
  371.         wrd(humilbuf[1]);            
  372.     }
  373. }

  374. void baojinpros()    //报警处理
  375. {
  376.     if(temp>=temph||humi>=humih)     //检测温度或者湿度高于设定上限值 降温湿
  377.     {
  378.         led1=1;        //降温湿指示灯
  379.         led2=0;
  380.     }
  381.     if(temp<=templ||humi<=humil)    //检测温度或者湿度低于设定下限值  升温湿
  382.     {
  383.         led1=0;
  384.         led2=1;  //升高温湿指示灯
  385.     }
  386.     if(DO==0)
  387.     {
  388.         led3=1;
  389.     }
  390.     if(DO==1)
  391.     {
  392.         led3=0;
  393.     }

  394.     if((temp>templ&&temp<temph)&&(humi>humil&&humi<humih)&&DO==1)
  395.     {
  396.         led1=0;
  397.         led2=0;
  398.         led3=0;
  399.     }
  400. }

  401. void Initial_com(void)
  402. {
  403. EA=1;        //开总中断
  404. ES=1;        //允许串口中断
  405. ET1=1;        //允许定时器T1的中断
  406. TMOD=0x20;   //定时器T1,在方式2中断产生波特率
  407. PCON=0x00;   //SMOD=0
  408. SCON=0x50;   // 方式1 由定时器控制
  409. TH1=0xfd;    //波特率设置为9600
  410. TL1=0xfd;
  411. TR1=1;       //开定时器T1运行控制位
  412. }

  413. void main()
  414. {
  415.     uint8 i=0;
  416.     led1=0;
  417.     led2=0;
  418.     led3=0;
  419.     Initial_com();
  420.     lcd_init();
  421.     if(DO==0)
  422.     {
  423.         delay1(1);      //消抖动
  424.         if(DO==0)      //确认触发
  425.         {
  426.                  SBUF=0X01;
  427.                  delay1(200);
  428.         }   
  429.          if(RI)
  430.          {
  431.             date=SBUF;    //单片机接受
  432.             SBUF=date;    //单片机发送
  433.             RI=0;
  434.           }
  435.     }
  436.     while(DHT11_Init())    //检测DHT11是否纯在
  437.     {
  438.         for(i=0;i<5;i++)
  439.         {
  440.             wrc(0x80+i);
  441.             wrd(str3[i]);   
  442.         }            
  443.     }
  444.     wrc(0x01);
  445.     lcd_init_display();       //LCD初始化显示
  446.     i=0;         
  447.     while(1)
  448.     {   
  449.         i++;
  450.         key_pros();
  451.         baojinpros();    //报警处理
  452.         if(i==15)
  453.         {
  454.             i=0;
  455.             data_pros();       //读取一次DHT11数据最少要大于100ms
  456.         }
  457.         delay(1000);
  458.         
  459.     }   
  460. }

复制代码



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

使用道具 举报

沙发
ID:345957 发表于 2018-6-6 10:11 | 只看该作者
学习一下
回复

使用道具 举报

板凳
ID:342081 发表于 2018-6-12 15:19 | 只看该作者
有仿真图吗
回复

使用道具 举报

地板
ID:429320 发表于 2018-12-19 10:34 | 只看该作者
有没有用在STM32F103ZET6上的
回复

使用道具 举报

5#
ID:718951 发表于 2020-3-30 17:56 | 只看该作者
请问有与51单片机的连接原理图吗
回复

使用道具 举报

6#
ID:982245 发表于 2021-11-20 13:57 | 只看该作者
有仿真嘛??
回复

使用道具 举报

7#
ID:1019895 发表于 2022-4-20 10:21 | 只看该作者
请教一下如何画仿真图
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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