找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 4049|回复: 5
收起左侧

单片机自动浇花+温湿度报警系统程序仿真设计 可设置湿度阈值

  [复制链接]
ID:753405 发表于 2020-6-21 23:14 | 显示全部楼层 |阅读模式
基于51单片机的自动浇花系统,可自设湿度阈值。
带有温湿度监测功能,可借鉴学习。
仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
51hei图片20200621230530.png 51hei图片20200621230525.png 51hei图片20200621230535.png

单片机源程序如下:
  1. #include <reg52.h>
  2. #include <intrins.h>
  3. #define uchar unsigned char                //宏定义
  4. #define uint unsigned int
  5. #include"eeprom.h"
  6. typedef unsigned char unint8;
  7. typedef unsigned char unint16;
  8. typedef unsigned int   U16;
  9. uchar code table[] = {"moisture:       "};
  10. uchar code table1[] ={"                "};
  11. uchar code table3[] ={" H:  %   H:   C "};
  12. uchar code table2[] ={"Set The:         "};
  13. sbit TRH = P1^4;//温湿度传感器DHT11数据接入
  14. sbit rs = P2^6;            
  15. sbit en = P2^7;
  16. sbit beep=P2^0;//蜂鸣器控制端

  17. sbit k1=P3^1;
  18. sbit k2=P3^2;
  19. sbit k3=P3^3;

  20. sbit jdq=P3^4;

  21. sbit CS   = P1^0;
  22. sbit Clk = P1^1;
  23. sbit DATI = P1^2;
  24. sbit DATO = P1^2;
  25. uchar stemp=35,shr=50,tr=80;           //温湿度上下线初始化
  26. bit yyp=1,lalarm=0;                                                  //设置标志位,报警标志位
  27. int key_delay=0;
  28. const int key_count=400;
  29. unsigned char dat = 0x00;      
  30. unsigned char CH;   
  31. uchar s1num,num,shis,shig,wens,weng;
  32. unint8 TH_data,TL_data,RH_data,RL_data,CK_data;
  33. unint8 TH_temp,TL_temp,RH_temp,RL_temp,CK_temp;
  34. unint8 com_data,untemp,temp;
  35. unint8 respond;
  36. void delay(uint x) //毫秒级延时函数
  37. {
  38.   uint i,j;
  39.   for(i=x;i>0;i--)
  40.      for(j=110;j>0;j--);
  41. }
  42. void di()                           //蜂鸣器报警
  43. {
  44.         beep=0;
  45.         delay(100);
  46.         beep=1;
  47. }
  48. void write_com(uchar com)
  49. {
  50.         rs=0;//命令
  51.         P0=com;
  52.         delay(5);
  53.         en=1;
  54.         delay(5);
  55.         en=0;
  56. }
  57. void write_date(uchar date)
  58. {
  59.         rs=1;//数据
  60.         P0=date;
  61.         delay(5);
  62.         en=1;
  63.         delay(5);
  64.         en=0;
  65. }
  66. void init1602()
  67. {
  68.         write_com(0x38);        //设置工作方式
  69.         write_com(0x0c);        //设置光标
  70.         write_com(0x06);        //设置输入方式
  71.         write_com(0x01);        //清屏
  72.         write_com(0x80);
  73.         for(num=0;num<16;num++)
  74.         {
  75.                 write_date(table[num]);
  76.         }
  77.         write_com(0x80+0x40);
  78.         for(num=0;num<16;num++)
  79.         {
  80.                 write_date(table1[num]);
  81.         }
  82. }
  83. void init16021()                //设置温度上下限显示初始化函数
  84. {
  85.         write_com(0x80);
  86.         for(num=0;num<16;num++)
  87.         {
  88.                 write_date(table2[num]);
  89.         }
  90.         write_com(0x80+0x40);
  91.         for(num=0;num<16;num++)
  92.         {
  93.                 write_date(table3[num]);
  94.         }
  95.         write_com(0x80+0x40+13);
  96.         write_date(0xdf);                 
  97.        
  98. }
  99. void write_H(uchar add,uchar date)
  100. {
  101.         uchar shi,ge;
  102.         shi=date/10;
  103.         ge=date%10;
  104.         write_com(0x80+0x40+add);
  105.         write_date(0x30+shi);
  106.         write_date(0x30+ge);
  107. }
  108. void write_tr(uchar add,uchar Data)
  109. {
  110.         uchar bai,shi,ge;
  111.         bai=Data/100;
  112.         shi=Data/10%10;
  113.         ge=Data%10;
  114.         write_com(0x80+add);
  115.         write_date(0X30+bai);
  116.         write_date(0X30+shi);
  117.         write_date(0X30+ge);
  118. }
  119. /////////////////////////////////
  120. /***********DHT11子程序*************************/
  121. /*********************************************************************************/

  122. /*********************************************************************************/
  123. // 毫秒级延时子程序
  124. /*********************************************************************************/
  125. void delay_ms(U16 j)
  126. {      unint8 i;
  127.             for(;j>0;j--)
  128.           {        
  129.                 for(i=0;i<27;i++);

  130.           }
  131. }
  132. /*********************************************************************************/

  133. /*********************************************************************************/
  134. //5us级延时程序
  135. /*********************************************************************************/
  136. void delay_us()
  137. {
  138.           unint8 i;
  139.           i--;
  140.           i--;
  141.           i--;
  142.           i--;
  143.           i--;
  144.           i--;
  145. }
  146. /********************************************************************************/

  147. /****************************************************************************/
  148. //收发信号检测,数据读取
  149. /****************************************************************************/
  150. char receive()
  151. {   
  152.           unint8 i;
  153.           for(i=0;i<8;i++)   
  154.          {
  155.                     respond=2;
  156.                     while((!TRH)&&respond++);
  157.                     delay_us();
  158.                     delay_us();
  159.                     delay_us();

  160.                                         temp=0;


  161.                     if(TRH)temp=1;
  162.                      respond=2;
  163.                      while((TRH)&&respond++);
  164.                                          //超时则跳出for循环                  
  165.                                          if(respond==1)break;

  166.                                                  //判断数据位是0还是1         
  167.                      
  168.                 // 如果高电平高过预定0高电平值则数据位为 1
  169.                     com_data<<=1;
  170.                     com_data|=temp;   
  171.           }
  172.           return(com_data);  
  173. }
  174. /****************************************************************************/

  175. /****************************************************************************/
  176. //湿度读取子程序
  177. //温度高8位== TL_data
  178. //温度低8位== TH_data
  179. //湿度高8位== RH_data
  180. //湿度低8位== RH_data
  181. //校验 8位 == CK_data
  182. //调用的程序有 delay();, Delay_5us();,RECEIVE();
  183. /***************************************************************************/
  184. void GET_TRH()
  185. {
  186.          //主机拉低18ms
  187.          TRH=0;
  188.          delay_ms(180);
  189.          TRH=1;
  190.          //DATA总线由上拉电阻拉高 主机延时20us
  191.          delay_us();
  192.          delay_us();
  193.          delay_us();
  194.          delay_us();
  195.          //主机设为输入 判断从机响应信号
  196.          TRH=1;
  197.          //判断DHT11是否有低电平响应信号 如不响应则跳出,响应则向下运行   
  198.          if(!TRH)   
  199.          {
  200.                 respond=2;
  201.                 //判断DHT11发出 80us 的低电平响应信号是否结束
  202.                 while((!TRH)&& respond++);
  203.                 respond=2;
  204.                 //判断从机是否发出 80us 的高电平,如发出则进入数据接收状态
  205.                 while(TRH && respond++);
  206.                        //数据接收状态   
  207.                 RH_temp = receive();
  208.                 RL_temp = receive();
  209.                 TH_temp = receive();
  210.                 TL_temp = receive();
  211.                 CK_temp = receive();
  212.                 TRH=1;//ST=1;     
  213.                 //数据校验
  214.                 untemp=(RH_temp+RL_temp+TH_temp+TL_temp);
  215.                 if(untemp==CK_temp)
  216.                 {
  217.                      RH_data = RH_temp;
  218.                      RL_data = RL_temp;
  219.                      TH_data = TH_temp;
  220.                      TL_data = TL_temp;
  221.                      CK_data = CK_temp;
  222.                 }
  223.         }
  224.                                 //湿度整数部分
  225.                          shis= (char)(0X30+RH_data/10);  //湿度的十位
  226.                          shig= (char)(0X30+RH_data%10);         //湿度的个
  227.                          //温度整数部分
  228.                          wens= (char)(0X30+TH_data/10);   //温度的十位
  229.                          weng= (char)(0X30+TH_data%10);         //温度的个位
  230.                                 //湿度整数部分
  231.                          shis= (char)(0X30+RH_data/10);  //湿度的十位
  232.                          shig= (char)(0X30+RH_data%10);         //湿度的个
  233.                          //温度整数部分
  234.                          wens= (char)(0X30+TH_data/10);   //温度的十位
  235.                          weng= (char)(0X30+TH_data%10);         //温度的个位
  236.                                 //温湿度显示函数
  237.                                  write_com(0x80+0x40+2);
  238.                                  write_date(shis);
  239.                                  write_date(shig);
  240.                                  write_date('%');         //湿度符号
  241.                                  write_com(0x80+0x40+9);
  242.                                  write_date(wens);
  243.                                  write_date(weng);
  244.                                  write_date(0xdf);        //温度符号
  245.                                  write_date('C');


  246. }
  247. /****按键扫描******/
  248. void keyscan()
  249. {
  250.         if(k1==0)
  251.         {
  252.                 delay(10);
  253.                 if(k1==0)
  254.                 {
  255.                         s1num++;
  256.                         while(!k1);                        //等待按键释放
  257.                         yyp=0;
  258.                         di();                       
  259.                         switch(s1num)
  260.                         {
  261.                                 case 1:        init16021();                                  //设置温度上下限初始化
  262.                                                 tr=byte_read(0x2000);
  263.                                                   shr=byte_read(0x2200);
  264.                                                   stemp=byte_read(0x2400);
  265.                                                 write_tr(9,tr);
  266.                                                 write_H(3,shr);
  267.                                                 write_H(11,stemp);
  268.                                                 write_com(0x80+11);
  269.                                                 write_com(0x0f);                        //打开光标
  270.                                                 break;
  271.                                 case 2:        write_com(0X40+0x80+4);
  272.                                                 break;
  273.                                 case 3:        write_com(0X40+0x80+12);
  274.                                                 break;
  275.                                 case 4:        s1num=0;
  276.                                                 write_com(0x0c);                        //关闭光标
  277.                                                 yyp=1;
  278.                                                 init1602();                                        //上电后显示初始化
  279.                                                 break;
  280.                         }               
  281.                 }
  282.         }
  283.         if(s1num!=0)
  284.         {
  285.                 if(k2==0)
  286.                 {
  287.                         delay(10);
  288.                         if(k2==0)
  289.                         {
  290.                                
  291.                                 while(!k2);                //等待按键释放
  292.                                 di();
  293.                                 switch(s1num)
  294.                         {
  295.                                         case 1: tr++;
  296.                                                         if(tr==255)tr=0;
  297.                                                         write_tr(9,tr);
  298.                                                         write_com(0x80+11);
  299.                                                         SectorErase(0x2000);//擦除扇区
  300.                                                            byte_write(0x2000,tr);//重新写入数据       
  301.                                                         break;
  302.                                         case 2: shr++;
  303.                                                         if(shr==85)shr=0;
  304.                                                         write_H(3,shr);
  305.                                                         write_com(0X40+0x80+4);       
  306.                                                         SectorErase(0x2200);//擦除扇区
  307.                                                            byte_write(0x2200,shr);//重新写入数据       
  308.                                                         break;
  309.                                         case 3: stemp++;
  310.                                                         if(stemp==45)stemp=0;
  311.                                                         write_H(11,stemp);
  312.                                                         write_com(0X40+0x80+12);
  313.                                                         SectorErase(0x2400);//擦除扇区
  314.                                                            byte_write(0x2400,stemp);//重新写入数据
  315.                                                     break;
  316.                                 }
  317.                         }
  318.                 }
  319.                 if(k3==0)
  320.                 {
  321.                         delay(10);
  322.                         if(k3==0)
  323.                         {
  324.                        
  325.                                 while(!k3);                //等待按键释放
  326.                                 di();
  327.                                 switch(s1num)
  328.                         {
  329.                                         case 1: tr--;
  330.                                                         if(tr==0)tr=255;
  331.                                                         write_tr(9,tr);
  332.                                                         write_com(0x80+11);
  333.                                                         SectorErase(0x2000);//擦除扇区
  334.                                                            byte_write(0x2000,tr);//重新写入数据               
  335.                                                         break;
  336.                                         case 2: shr--;
  337.                                                         if(shr==0)shr=85;
  338.                                                         write_H(3,shr);
  339.                                                         write_com(0X40+0x80+4);       
  340.                                                         SectorErase(0x2200);//擦除扇区
  341.                                                            byte_write(0x2200,shr);//重新写入数据
  342.                                                         break;
  343.                                         case 3: stemp--;
  344.                                                         if(stemp==0)stemp=45;
  345.                                                         write_H(11,stemp);
  346.                                                         write_com(0X40+0x80+12);
  347.                                                         SectorErase(0x2400);//擦除扇区
  348.                                                            byte_write(0x2400,stemp);//重新写入数据
  349.                                                     break;
  350.                                 }
  351.                         }
  352.                 }
  353.         }
  354. }

  355. unsigned char adc0832(unsigned char CH)
  356. {        
  357.         unsigned char i,test,adval;      
  358.         adval = 0x00;      
  359.         test = 0x00;      
  360.         Clk = 0;       //初始化      
  361.         DATI = 1;     
  362.         _nop_();     
  363.         CS = 0;     
  364.         _nop_();     
  365.         Clk = 1;   
  366.         _nop_();      
  367.         if ( CH == 0x00 )      //通道选择   
  368.         {         
  369.                 Clk = 0;         
  370.                 DATI = 1;      //通道0的第一位      
  371.                  _nop_();      
  372.                  Clk = 1;         
  373.                  _nop_();         
  374.                  Clk = 0;        
  375.                  DATI = 0;      //通道0的第二位      
  376.                  _nop_();  
  377.                  Clk = 1;      
  378.                  _nop_();     
  379.         }      
  380.         else     
  381.         {         
  382.                 Clk = 0;        
  383.                 DATI = 1;      //通道1的第一位        
  384.                 _nop_();        
  385.                 Clk = 1;        
  386.                 _nop_();        
  387.                 Clk = 0;        
  388.                 DATI = 1;      //通道1的第二位     
  389.                 _nop_();      
  390.                 Clk = 1;      
  391.                 _nop_();     
  392.         }        
  393.                 Clk = 0;      
  394.                 DATI = 1;        
  395.                 for( i = 0;i < 8;i++ )      //读取前8位的值     
  396.                 {         
  397.                         _nop_();         
  398.                         adval <<= 1;        
  399.                         Clk = 1;        
  400.                         _nop_();        
  401.                         Clk = 0;        
  402.                         if (DATO)            
  403.                         adval |= 0x01;      
  404.                         else            
  405.                         adval |= 0x00;     
  406.                 }         
  407.                 for (i = 0; i < 8; i++)      //读取后8位的值      
  408.                 {            
  409.                         test >>= 1;            
  410.                         if (DATO)               
  411.                         test |= 0x80;            
  412.                         else                 
  413.                         test |= 0x00;            
  414.                         _nop_();           
  415.                         Clk = 1;           
  416.                         _nop_();           
  417.                         Clk = 0;      
  418.                 }        
  419.                 if (adval == test)      //比较前8位与后8位的值,如果不相同舍去。若一直出现显示为零,请将该行去掉            
  420.                 dat = test;        
  421.                 _nop_();         
  422.                 CS = 1;        //释放ADC0832        
  423.                 DATO = 1;        
  424.                 Clk = 1;      
  425.                 return dat;
  426. }
  427. void display(uchar Data)
  428. {
  429.         uchar bai,shi,ge;
  430.         bai=Data/100;
  431.         shi=Data/10%10;
  432.         ge=Data%10;
  433.         write_com(0x80+9);
  434.         write_date(0X30+bai);
  435.         write_date(0X30+shi);
  436.         write_date(0X30+ge);
  437. }
  438. void baojing()
  439. {
  440.                         if(TH_data>stemp||RH_data>shr)//判断温湿度
  441.                         {
  442.                                 lalarm=1;
  443.                                 if(RH_data>shr) //        报警
  444.                                 {
  445.                                                
  446.                                 }
  447.                                  if(TH_data>stemp) //        报警
  448. ……………………

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

所有资料51hei提供下载:
自动浇花系统+温湿度监测.zip (762.24 KB, 下载次数: 145)

评分

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

查看全部评分

回复

使用道具 举报

ID:790946 发表于 2020-6-29 15:18 | 显示全部楼层
你的仿真图怎么运行操作呀
回复

使用道具 举报

ID:793756 发表于 2020-7-15 09:42 | 显示全部楼层
仿真图里少了点东西吧
回复

使用道具 举报

ID:826049 发表于 2020-10-9 10:10 | 显示全部楼层
p3.1的k1按键能不能用别的接口代替?p3.1我要拿来写程序好像不能使用
回复

使用道具 举报

ID:826049 发表于 2020-10-20 20:41 | 显示全部楼层
你这个东西的元器件库有没有啊,我找不到封装库库
回复

使用道具 举报

ID:406598 发表于 2020-11-2 14:30 | 显示全部楼层
哈哈哈4399 发表于 2020-6-29 15:18
你的仿真图怎么运行操作呀

click here bc6da4fb3f3f0cc519053e7861c3e535.png
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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