找回密码
 立即注册

QQ登录

只需一步,快速开始

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

单片机孵化环境温湿度监控系统程序设计

[复制链接]
跳转到指定楼层
楼主
ID:546095 发表于 2019-5-24 09:26 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
/*
实验说明:
    根据自己使用的LCD1602是否带有转接板,如果带有转接板的即为4位,需在LCD.H头文件中
    将宏#define LCD1602_4PINS打开,我们这里使用的LCD1602是8位,所以默认将该宏注释。
实验接线:
    LCD1602液晶模块-->单片机管脚
    参考LCD1602液晶显示实验接线(开发攻略内在对应的实验章节内实验现象有接线说明)
    DHT11温湿度传感器模块-->单片机管脚
    使用杜邦线将DHT11模块数据口与单片机P32口连接,模块的电源和地也要与开发板电源和地连接
    DS18B20温度传感器模块-->单片机管脚
    参考DS18B20温度传感器实验接线
    J14-->P37
    独立按键模块-->单片机管脚
    K1-->P33
    K2-->P21
    K3-->P22
    LED灯模块-->单片机管脚
    D1-->P35
    D2-->P36

实验现象:
    首先检测DHT11是否连接成功,如果没有连接好,则LCD1602上显示ERROR。通过按键K1可对温湿度阀值进行设定
    按下一次K1,进入温度上限设定,再按下K1一次,进入温度下限设定,再按下一次K1,进入湿度上限设定,
    再按下一次K1,进入湿度下限设定,再按下一次K1,退出模式选择,进入正常温湿度采集状态。
    选择好要设定的模式,然后通过K2和K3进行数值加减。当采集的温度或者湿度高于设定上限值,降温湿指示灯D1
    亮,当采集的温度或者湿度低于设定下限值,升温湿指示灯D2亮,温湿度正常范围内,D1和D2指示灯不亮。
*/

单片机源程序如下:
  1. #include<reg51.h>
  2. #include "intrins.h"
  3. #include"lcd.h"
  4. typedef unsigned char uint8;
  5. typedef unsigned int uint16;


  6. sbit k1=P3^3; //模式
  7. sbit k2=P2^1; //加
  8. sbit k3=P2^2; //减

  9. sbit DHT11_DQ_OUT=P3^2;
  10. sbit led1=P3^5;
  11. sbit led2=P3^6;

  12. sbit dq=P3^7;

  13. uint8 mode=0,xian;
  14. char temph=50,templ=20;
  15. char humih=80,humil=20;
  16. uint8 temp,humi;
  17. uint8 flag;   //设定报警标志
  18. uint8 a,c,tempvalue;
  19. uint8 code num[10]="0123456789";

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


  29. void delay(uint16 i)
  30. {
  31.     while(i--);
  32. }

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

  38. void wrc(uint8 c)    //写命令
  39. {
  40.     LcdWriteCom(c);
  41. }
  42. void wrd(uint8 dat)   //写数据
  43. {
  44.     LcdWriteData(dat);
  45. }
  46. void lcd_init()    // LCD1602初始化
  47. {
  48.     LcdInit();
  49. }
  50. //复位DHT11
  51. void DHT11_Rst()      
  52. {                 
  53.     DHT11_DQ_OUT=0;     //拉低DQ
  54.     delay_ms(20);       //拉低至少18ms
  55.     DHT11_DQ_OUT=1;     //DQ=1
  56.     delay(3);       //主机拉高20~40us
  57. }

  58. //等待DHT11的回应
  59. //返回1:未检测到DHT11的存在
  60. //返回0:存在
  61. uint8 DHT11_Check()        
  62. {   
  63.     uint8 retry=0;   
  64.     while (DHT11_DQ_OUT&&retry<100)//DHT11会拉低40~50us
  65.     {
  66.         retry++;
  67.         _nop_();
  68.     };   
  69.     if(retry>=100)return 1;
  70.     else retry=0;
  71.     while (!DHT11_DQ_OUT&&retry<100)//DHT11拉低后会再次拉高40~50us
  72.     {
  73.         retry++;
  74.         _nop_();
  75.     };
  76.     if(retry>=100)return 1;     
  77.     return 0;
  78. }


  79. //DHT11初始化
  80. //返回0:初始化成功,1:失败
  81. uint8 DHT11_Init()
  82. {
  83.     DHT11_Rst();      
  84.     return DHT11_Check();   
  85. }


  86. //从DHT11读取一个位
  87. //返回值:1/0
  88. uint8 DHT11_Read_Bit(void)           
  89. {
  90.     uint8 retry=0;
  91.     while(DHT11_DQ_OUT&&retry<100)//等待变为低电平 12-14us 开始
  92.     {
  93.         retry++;
  94.         _nop_();
  95.     }
  96.     retry=0;
  97.     while((!DHT11_DQ_OUT)&&retry<100)//等待变高电平    26-28us表示0,116-118us表示1
  98.     {
  99.         retry++;
  100.         _nop_();
  101.     }
  102.     delay(1);//等待40us
  103.     if(DHT11_DQ_OUT)return 1;
  104.     else return 0;         
  105. }

  106. //从DHT11读取一个字节
  107. //返回值:读到的数据
  108. uint8 DHT11_Read_Byte(void)   
  109. {        
  110.     uint8 i,dat=0;
  111.     for (i=0;i<8;i++)
  112.     {
  113.         dat<<=1;
  114.         dat|=DHT11_Read_Bit();
  115.     }                           
  116.     return dat;
  117. }

  118. //从DHT11读取一次数据
  119. //temp:温度值(范围:0~50°)
  120. //humi:湿度值(范围:20%~90%)
  121. //返回值:0,正常;1,读取失败
  122. uint8 DHT11_Read_Data(uint8 *temp,uint8 *humi)
  123. {
  124.     uint8 buf[5];
  125.     uint8 i;
  126.     DHT11_Rst();
  127.     if(DHT11_Check()==0)
  128.     {
  129.         for(i=0;i<5;i++)//读取40位数据
  130.         {
  131.             buf[i]=DHT11_Read_Byte();
  132.         }
  133.         if((buf[0]+buf[1]+buf[2]+buf[3])==buf[4])
  134.         {
  135.             *humi=buf[0];
  136.             *temp=buf[2];
  137.         }

  138.     }else return 1;
  139.     return 0;
  140. }




  141. void ds18b20init()      //18b20的初始化
  142. {
  143.     dq=1;
  144.     delay(1);
  145.     dq=0;
  146.     delay(80);
  147.     dq=1;
  148.     delay(5);
  149.     dq=0;
  150.     delay(20);
  151.     dq=1;
  152.     delay(35);
  153. }
  154. void ds18b20wr(uint8 dat)     //18b20写数据
  155. {
  156.     uint8 i;
  157.     for(i=0;i<8;i++)
  158.     {
  159.         dq=0;
  160.         dq=dat&0x01;
  161.         dat>>=1;
  162.         delay(8);//在时序上只有这一块对时序要求最准确,他的时间必须大于15us
  163.         dq=1;
  164.         delay(1);
  165.     }   
  166. }
  167. uint8 ds18b20rd()         //18b20读数据
  168. {
  169.     uint8 value,i;
  170.     for(i=0;i<8;i++)   
  171.     {
  172.         dq=0;
  173.         value>>=1;
  174.         dq=1;
  175.         if(dq==1)value|=0x80;
  176.         delay(8);//在这一块也对时间要求特别准确,整段程序必须大于60us
  177.     }
  178.     return value;
  179. }
  180. uint8 readtemp()              //读取温度内需要复位的
  181. {
  182.     uint8 b;
  183.     ds18b20init();      //初始化
  184.     ds18b20wr(0xcc);   //发送忽略ROM指令
  185.     ds18b20wr(0x44);   //发送温度转换指令
  186.     delay(100);
  187.     ds18b20init();     //初始化
  188.     ds18b20wr(0xcc);   //发送忽略ROM指令
  189.     ds18b20wr(0xbe);   //发读暂存器指令
  190.     a=ds18b20rd();   //温度的低八位
  191.     b=ds18b20rd();   //温度的高八位
  192.     b<<=4;           //ssss s***;s为标志位s=0表示温度值为正数,s=1温度值为负数
  193.     c=b&0x80;       //温度正负标志位确认
  194.     b+=(a&0xf0)>>4;
  195.     a=a&0x0f;     //温度的小数部分
  196.     return b;
  197. }


  198. void key_pros()  //按键处理函数
  199. {
  200.     if(k1==0)
  201.     {
  202.         delay(1000);
  203.         if(k1==0)
  204.         {
  205.             mode++;
  206.             if(mode==5)mode=0;
  207.             wrc(0x01);
  208.         }
  209.         while(!k1);
  210.     }
  211.     if(mode==1)       //对温度上限设定
  212.     {
  213.         if(k2==0)         //加
  214.         {
  215.             delay(1000);
  216.             if(k2==0)
  217.             {
  218.                 temph++;
  219.                 if(temph>=80)temph=80;
  220.             }
  221.             while(!k2);
  222.         }
  223.         if(k3==0)      //减
  224.         {
  225.             delay(1000);
  226.             if(k3==0)
  227.             {
  228.                 temph--;
  229.                 if(temph<=0)temph=0;
  230.             }
  231.             while(!k3);
  232.         }
  233.     }
  234.     if(mode==2)       //对温度下限设定
  235.     {
  236.         if(k2==0)         //加
  237.         {
  238.             delay(1000);
  239.             if(k2==0)
  240.             {
  241.                 templ++;
  242.                 if(templ>=80)templ=80;
  243.             }
  244.             while(!k2);
  245.         }
  246.         if(k3==0)      //减
  247.         {
  248.             delay(1000);
  249.             if(k3==0)
  250.             {
  251.                 templ--;
  252.                 if(templ<=0)templ=0;
  253.             }
  254.             while(!k3);
  255.         }
  256.     }
  257.     if(mode==3)       //对湿度上限设定
  258.     {
  259.         if(k2==0)         //加
  260.         {
  261.             delay(1000);
  262.             if(k2==0)
  263.             {
  264.                 humih++;
  265.                 if(humih>=80)humih=80;
  266.             }
  267.             while(!k2);
  268.         }
  269.         if(k3==0)      //减
  270.         {
  271.             delay(1000);
  272.             if(k3==0)
  273.             {
  274.                 humih--;
  275.                 if(humih<=0)humih=0;
  276.             }
  277.             while(!k3);
  278.         }
  279.     }
  280.     if(mode==4)       //对湿度下限设定
  281.     {
  282.         if(k2==0)         //加
  283.         {
  284.             delay(1000);
  285.             if(k2==0)
  286.             {
  287.                 humil++;
  288.                 if(humil>=80)humil=80;
  289.             }
  290.             while(!k2);
  291.         }
  292.         if(k3==0)      //减
  293.         {
  294.             delay(1000);
  295.             if(k3==0)
  296.             {
  297.                 humil--;
  298.                 if(humil<=0)humil=0;
  299.             }
  300.             while(!k3);
  301.         }
  302.     }
  303. }

  304. void lcd_init_display()    //LCD初始化显示
  305. {
  306.     uint8 i;
  307.     for(i=0;i<5;i++)
  308.     {
  309.         wrc(0x80+i);
  310.         wrd(str1[i]);
  311.     }

  312.     for(i=0;i<5;i++)
  313.     {
  314.         wrc(0xc0+i);
  315.         wrd(str2[i]);   
  316.     }
  317. }

  318. void data_pros()    //数据处理函数
  319. {
  320.     uint8 i;        
  321.     uint8 temp_buf[2],humi_buf[2];
  322.     uint8 temphbuf[2],templbuf[2],humihbuf[2],humilbuf[2];
  323.     float dio;
  324.     uint16 k;

  325.     tempvalue=readtemp();
  326.     DHT11_Read_Data(&temp,&humi);
  327.     temp_buf[0]=temp/10+0x30;   
  328.     temp_buf[1]=temp%10+0x30;

  329.     humi_buf[0]=humi/10+0x30;
  330.     humi_buf[1]=humi%10+0x30;

  331.     dio=a*0.0625;
  332.     k=dio*10000;//取小数点后两位有效数字

  333.     temphbuf[0]=temph/10+0x30;
  334.     temphbuf[1]=temph%10+0x30;
  335.     templbuf[0]=templ/10+0x30;
  336.     templbuf[1]=templ%10+0x30;

  337.     humihbuf[0]=humih/10+0x30;
  338.     humihbuf[1]=humih%10+0x30;
  339.     humilbuf[0]=humil/10+0x30;
  340.     humilbuf[1]=humil%10+0x30;

  341.     if(mode==0)
  342.     {
  343.         lcd_init_display();
  344.         wrc(0x85);
  345.         wrd(num[tempvalue%100/10]);
  346.         wrd(num[tempvalue%100%10]);
  347.         wrd('.');
  348.         wrd(num[k/1000]);
  349.         wrd(0xdf);
  350.         wrd('C');

  351.         for(i=0;i<2;i++)
  352.         {
  353.             wrc(0Xc5+i);
  354.             wrd(humi_buf[i]);         
  355.         }   
  356.         for(i=0;i<3;i++)
  357.         {
  358.             wrc(0Xc7+i);
  359.             wrd(str5[i]);         
  360.         }
  361.     }
  362.     if(mode==1)           //温度上限显示
  363.     {
  364.         wrc(0x80);
  365.         for(i=0;i<6;i++)
  366.         {
  367.             wrd(str6[i]);         
  368.         }
  369.         wrd(temphbuf[0]);
  370.         wrd(temphbuf[1]);           
  371.     }
  372.     if(mode==2)           //温度下限显示
  373.     {
  374.         wrc(0x80);
  375.         for(i=0;i<6;i++)
  376.         {
  377.             wrd(str7[i]);         
  378.         }
  379.         wrd(templbuf[0]);
  380.         wrd(templbuf[1]);
  381.     }
  382.     if(mode==3)           //湿度上限显示
  383.     {
  384.         wrc(0x80);
  385.         for(i=0;i<6;i++)
  386.         {
  387.             wrd(str8[i]);         
  388.         }
  389.         wrd(humihbuf[0]);
  390.         wrd(humihbuf[1]);           
  391.     }
  392.     if(mode==4)           //湿度下限显示
  393.     {
  394.         wrc(0x80);
  395.         for(i=0;i<6;i++)
  396.         {
  397.             wrd(str9[i]);         
  398.         }
  399.         wrd(humilbuf[0]);
  400.         wrd(humilbuf[1]);
  401.     }
  402. }

  403. void baojinpros()   //报警处理
  404. {
  405.     if(tempvalue>=temph||humi>=humih)    //检测温度或者湿度高于设定上限值 降温湿
  406.     {
  407.         led1=1;     //降温湿指示灯
  408.         led2=0;
  409.     }
  410.     if(tempvalue<=templ||humi<=humil)   //检测温度或者湿度低于设定下限值  升温湿
  411.     {
  412.         led1=0;
  413.         led2=1;    //升高温湿指示灯
  414.     }
  415.     if((tempvalue>templ&&tempvalue<temph)&&(humi>humil&&humi<humih))
  416.     {
  417.         led1=0;
  418.         led2=0;
  419.     }
  420. }

  421. void main()
  422. {
  423.     uint8 i=0;
  424.     led1=0;
  425.     led2=0;
  426.     lcd_init();
  427.     while(DHT11_Init()) //检测DHT11是否纯在
  428.     {
  429.         for(i=0;i<5;i++)
  430.         {
  431.             wrc(0x80+i);
  432.             wrd(str3[i]);   
  433.         }           
  434.     }
  435.     wrc(0x01);
  436.     lcd_init_display();    //LCD初始化显示
  437.     i=0;
  438.     while(1)
  439.     {   
  440.         i++;
  441.         key_pros();
  442.         baojinpros();   //报警处理
  443.         if(i==15)
  444.         {
  445.             i=0;
  446.             data_pros();     //读取一次DHT11数据最少要大于100ms
  447.         }
  448.         delay(1000);

  449.     }
  450. }
复制代码


评分

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

查看全部评分

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

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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