找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 4771|回复: 1
收起左侧

单片机大棚温湿度检测制作 Proteus仿真程序

[复制链接]
ID:698919 发表于 2020-2-27 10:36 | 显示全部楼层 |阅读模式
Altium Designer画的单片机大棚温湿度检测原理图和PCB图如下:(51hei附件中可下载工程文件)
51hei.png 51hei.png

仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
51hei.png

制作出来的实物图如下:
00006-1.jpg 00006-2.jpg 00006-M.jpg 00006-B.jpg 00006-Z.jpg P0006-1.jpg P0006-2.jpg P0006-3.jpg P0006-M.jpg P0006-B.jpg

单片机源程序如下:
  1. /*************************************************************
  2.                       大棚温湿度检测

  3. 补充说明:
  4. ***************************************************************/
  5. #include<reg52.h>          //头文件
  6. #include<LCD1602.h>
  7. #include<AT24C02.h>
  8. #include<DHT11.h>

  9. /*****************灯、蜂鸣器、按键引脚定义*******************/
  10. sbit led     = P3^7;  //超限指示灯
  11. sbit led1    = P3^2;  //正常指示灯
  12. sbit buzz    = P2^3;  //蜂鸣器
  13. sbit key_set = P1^0;  //设置键
  14. sbit key_jia = P1^3;  //加键
  15. sbit key_jian= P1^6;  //减键

  16. /************************变量定义***********************/
  17. uchar temp_old,humi_old;//存储上一次的温度、湿度
  18. uchar temp_up,temp_down;//存储温度上、下限值
  19. uchar humi_up,humi_down;//存储湿度上、下限值
  20. uchar set_f;                           //设置选择标记,=0非设置,=1设置湿度上限,=2设置湿度下限
  21.                                             //              =3设置温度上限,=4设置温度下限。
  22. uchar T0_num;                        //计数变量

  23. /********************************************************
  24. 函数名称:void display(void)
  25. 函数作用:LCD1602显示固定的内容
  26. 参数说明:
  27. ********************************************************/
  28. void fixed_display(void)
  29. {
  30.         lcd1602_write_character(0,1,"Humi:");//0:表示第1列,1:表示第1行,所有关于显示都一样
  31.         lcd1602_write_character(0,2,"Temp:");//0:表示第1列,2:表示第2行,所有关于显示都一样
  32.         lcd1602_write_character(12,1,"%RH"); //12:表示第13列,2:表示第1行,所有关于显示都一样
  33.         LCD_disp_char(12,2,0x00);                         //显示自定义字符‘°’
  34.         LCD_disp_char(13,2,'C');                         //显示‘C’
  35. }
  36. /********************************************************
  37. 函数名称:void display1(void)
  38. 函数作用:显示当前实际温湿度
  39. 参数说明:
  40. ********************************************************/
  41. void display1(void)
  42. {
  43.         if(DHT11_Check()==1)                  //判断校验和是否正确
  44.         {
  45.                 if(humi_old<Humi_H)                                  //判断湿度是否上升
  46.                 {
  47.                         LCD_disp_char(15,1,0x01);          //显示‘↑’
  48.                         Delay_ms(50);                                  //延时
  49.                         humi_old=Humi_H;                          //记录当前湿度
  50.                 }
  51.                 else
  52.                         if(humi_old>Humi_H)                          //判断湿度是否下降
  53.                         {
  54.                                 LCD_disp_char(15,1,0x02); //显示‘↓’
  55.                                 Delay_ms(50);                          //延时
  56.                                 humi_old=Humi_H;                  //记录当前湿度
  57.                         }

  58.                 if(temp_old<Temp_H)                                  //判断温度是否上升
  59.                 {
  60.                         LCD_disp_char(15,2,0x01);          //显示‘↑’
  61.                         Delay_ms(50);                                  //延时
  62.                         temp_old=Temp_H;                          //记录当前温度
  63.                 }
  64.                 else
  65.                         if(temp_old>Temp_H)                          //判断温度是否下降
  66.                         {
  67.                                 LCD_disp_char(15,2,0x02); //显示‘↓’
  68.                                 Delay_ms(50);                          //延时
  69.                                 temp_old=Temp_H;                  //记录当前温度
  70.                         }
  71.                 //显示实测湿度值
  72.                 LCD_disp_char(6,1,ASCII[Humi_H/10]);           
  73.                 LCD_disp_char(7,1,ASCII[Humi_H%10]);
  74.                 LCD_disp_char(8,1,ASCII[12]);
  75.                 LCD_disp_char(9,1,ASCII[Humi_L%10]);
  76.                 LCD_disp_char(10,1,'0');
  77.                 //显示实测温度值
  78.                 LCD_disp_char(6,2,ASCII[Temp_H/10]);           
  79.                 LCD_disp_char(7,2,ASCII[Temp_H%10]);
  80.                 LCD_disp_char(8,2,ASCII[12]);
  81.                 LCD_disp_char(9,2,ASCII[Temp_L%10]);
  82.                 LCD_disp_char(10,2,'0');
  83.                
  84.                 if(temp_up<=Temp_H||temp_down>Temp_H||humi_up<=Humi_H||humi_down>Humi_H) //判断是否超出设置的温湿度上下限
  85.                 {
  86.                         buzz=0;                 //超出的话蜂鸣器响起
  87.                         led=0;                 //点亮报警灯
  88.                         led1=1;
  89.                 }
  90.                 else                     //否者温湿度都处于限值范围内
  91.                 {
  92.                         buzz=1;                 //关闭蜂鸣器
  93.                         led=1;               
  94.                         led1=0;                 //点亮正常灯
  95.                 }                                                
  96.         }        
  97. }
  98. /********************************************************
  99. 函数名称:void display2(void)
  100. 函数作用:显示设置时温湿度上下限
  101. 参数说明:
  102. ********************************************************/
  103. void display2(void)
  104. {
  105.         T0_num++;

  106.         lcd1602_write_character(0,1,"Humi:Up");
  107.         lcd1602_write_character(0,2,"Temp:Up");
  108.         lcd1602_write_character(9,1,",Down");
  109.         lcd1602_write_character(9,2,",Down");

  110.         if(T0_num%2==0)        //偶数次显示,奇数次不显示。这样就会有闪烁效果,可以清楚看到当前设置的是哪个值
  111.         {
  112.                 LCD_disp_char(7,1,ASCII[humi_up/10]);           //显示 湿度上限
  113.                 LCD_disp_char(8,1,ASCII[humi_up%10]);
  114.                 LCD_disp_char(14,1,ASCII[humi_down/10]);   //显示 湿度下限
  115.                 LCD_disp_char(15,1,ASCII[humi_down%10]);
  116.         
  117.                 LCD_disp_char(7,2,ASCII[temp_up/10]);           //显示 温度上限
  118.                 LCD_disp_char(8,2,ASCII[temp_up%10]);
  119.                 LCD_disp_char(14,2,ASCII[temp_down/10]);   //显示 温度下限
  120.                 LCD_disp_char(15,2,ASCII[temp_down%10]);
  121.                 Delay_ms(1);
  122.         }
  123.         else                         //奇数次不显示
  124.         {
  125.                 switch(set_f)//根据当前设置的内容,对应位置闪烁
  126.                 {
  127.                         case 1:lcd1602_write_character(7,1,"  "); break;
  128.                         case 2:lcd1602_write_character(14,1,"  "); break;
  129.                         case 3:lcd1602_write_character(7,2,"  "); break;
  130.                         case 4:lcd1602_write_character(14,2,"  "); break;
  131.                         default: break;
  132.                 }
  133.         }
  134. }
  135. /********************************************************
  136. 函数名称:void delayms(uint ms)
  137. 函数作用:毫秒延时函数
  138. 参数说明:
  139. ********************************************************/
  140. void delayms(uint ms)
  141. {
  142.         unsigned char i=100,j;
  143.         for(;ms;ms--)
  144.         {
  145.                 while(--i)
  146.                 {
  147.                         j=10;
  148.                         while(--j);
  149.                 }
  150.         }
  151. }
  152. /********************************************************
  153. 函数名称:void scan(void)
  154. 函数作用:按键检测函数
  155. 参数说明:
  156. ********************************************************/
  157. void scan(void)
  158. {        
  159.         //设置键,不支持连按
  160.         if(key_set==0)                //按键按下
  161.         {
  162.                 delayms(7);                //延时消抖
  163.                 if(key_set==0)        //再次确认按键按下
  164.                 {
  165.                         led=1;            //关闭报警灯
  166.                         led1=1;
  167.                         buzz=1;            //关闭蜂鸣器
  168.                         if(set_f==0)//进入设置先清除屏幕,显示设置部分
  169.                         {
  170.                                 LCD_write_command(0x01);        //清除屏幕显示
  171.                                 delay_n40us(100);                        //延时等待全部清除完毕
  172.                         }
  173.                         set_f++;        //设置变量+1
  174.                         if(set_f==5)//全部设置完成,退出设置
  175.                         {
  176.                                 set_f=0;//重置设置变量

  177.                                 AT24C02_write_date(0,humi_up);  //写入【湿度上限】数据保存
  178.                                 AT24C02_write_date(1,humi_down);//写入【湿度下限】数据保存
  179.                                 AT24C02_write_date(2,temp_up);  //写入【温度上限】数据保存
  180.                                 AT24C02_write_date(3,temp_down);//写入【温度下限】数据保存
  181.                                 
  182.                                 LCD_write_command(0x01);        //清除屏幕显示
  183.                                 delay_n40us(100);                        //延时等待全部清除完毕
  184.                                 fixed_display();                         //清除显示后显示固定部分
  185.                         }                        
  186.                 }
  187.                 while(!key_set);//检测按键松开
  188.         }

  189.         //加值键,支持连按
  190.         if(key_jia==0&&set_f!=0)
  191.         {
  192.                 delayms(7);
  193.                 if(key_jia==0)
  194.                 {
  195.                         if(set_f==1)        //设置 湿度上限值
  196.                         {
  197.                                 if(humi_up<99)  //最大值可设置99%RH
  198.                                         humi_up++;  //湿度上限+1%RH
  199.                         }
  200.         
  201.                         if(set_f==2)        //设置 湿度下限值
  202.                         {
  203.                                 if(humi_down<99&&humi_down+1<humi_up)//最大值可设置99%RH,并且下限不可超过上限
  204.                                         humi_down++;//湿度下限+1%RH
  205.                         }
  206.         
  207.                         if(set_f==3)        //设置 温度上限值
  208.                         {
  209.                                 if(temp_up<99)  //最大值可设置99℃
  210.                                         temp_up++;  //湿度上限+1℃
  211.                         }
  212.         
  213.                         if(set_f==4)        //设置 温度下限值
  214.                         {
  215.                                 if(temp_down<99&&temp_down+1<temp_up)//最大值可设置99℃,并且下限不可超过上限
  216.                                         temp_down++;//温度下限+1℃
  217.                         }
  218.                 }
  219.         }

  220.         //减值键,支持连按
  221.         if(key_jian==0&&set_f!=0)
  222.         {
  223.                 delayms(7);
  224.                 if(key_jian==0)
  225.                 {
  226.                         if(set_f==1)        //设置湿度上限值
  227.                         {
  228.                                 if(humi_up!=0&&humi_up>humi_down+1)//最小值可设置0%RH,并且上限得比下限大
  229.                                         humi_up--;  //湿度上限值-1%RH
  230.                         }
  231.         
  232.                         if(set_f==2)        //设置湿度下限值
  233.                         {
  234.                                 if(humi_down!=0)//最小值可设置0%RH
  235.                                         humi_down--;//湿度下限值-1%RH
  236.                         }
  237.         
  238.                         if(set_f==3)        //设置温度上限值
  239.                         {
  240.                                 if(temp_up!=0&&temp_up>temp_down+1)//最小值可设置0℃,并且上限得比下限大
  241.                                         temp_up--;  //温度上限值-1℃
  242.                         }
  243.         
  244.                         if(set_f==4)        //设置温度下限值
  245.                         {
  246.                                 if(temp_down!=0)//最小值可设置0℃
  247.                                         temp_down--;//温度下限值-1℃
  248.                         }
  249.                 }
  250.         }
  251. }
  252. /********************************************************
  253. 函数名称:void main()
  254. 函数作用:主函数
  255. 参数说明:
  256. ********************************************************/
  257. void main()
  258. {
  259.         if(key_jian==0)
  260.         {
  261.                 delayms(100);
  262.                 if(key_jian==0)
  263.                 {
  264.                         AT24C02_write_date(0,75);//写入【湿度上限值】数据保存
  265.                         AT24C02_write_date(1,45);//写入【湿度下限值】数据保存
  266.                         AT24C02_write_date(2,30);//写入【温度上限值】数据保存
  267.                         AT24C02_write_date(3,16);//写入【温度下限值】数据保存
  268.                 }
  269.         }

  270.         humi_up=AT24C02_read_date(0);  //读取存储的【湿度上限值】数据
  271.         humi_down=AT24C02_read_date(1);//读取存储的【湿度下限值】数据
  272.         temp_up=AT24C02_read_date(2);  //读取存储的【温度上限值】数据
  273.         temp_down=AT24C02_read_date(3);//读取存储的【温度下限值】数据

  274.         LCD_init();                    //初始化LCD1602
  275.         lcd1602_write_pic(0x00,pic);   //将自定义字符“°”写入到LCD1602中
  276.         lcd1602_write_pic(0x01,zeng);  //将自定义字符“↑”写入到LCD1602中
  277.         lcd1602_write_pic(0x02,jian);  //将自定义字符“↓”写入到LCD1602中

  278.         fixed_display();               //显示固定内容
  279.         while(1)
  280.         {
  281.                 scan();                               //按键检测处理
  282.                 if(set_f==0)                           //正常显示模式
  283.                 {
  284.                         DHT11_read();          //读取DHT11温湿度
  285.                         display1();                   //显示当前温、湿度
  286.                 }
  287.                 else
  288.                         display2();                   //显示设置温湿度上下限
  289.         }
  290. }
复制代码

所有资料51hei提供下载:
大棚温湿度检测.7z (2.2 MB, 下载次数: 147)
回复

使用道具 举报

ID:710465 发表于 2020-3-22 22:25 来自手机 | 显示全部楼层
用附带的main.c文件代码,生成新的hex文件,放到仿真中运行出错咋回事
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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