找回密码
 注册
关于网站域名变更的通知
查看: 135|回复: 2
打印 上一主题 下一主题

单片机大棚温湿度检测与控制程序+Proteus仿真 LCD1602显示

[复制链接]

该用户从未签到

跳转到指定楼层
1#
发表于 2022-6-22 09:39 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

EDA365欢迎您登录!

您需要 登录 才可以下载或查看,没有帐号?注册

x
大棚温湿度,检测与控制LCD1602显示温度与湿度,温度大于设定值时开风扇,小于时开电辅热,使得气温保持一定限制,同时利用AD采集湿度,然后进行浇水。
$ A- o: ?+ i* w4 P/ s
  [' T& o* Q, {1 N仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
7 O# l$ ]: q3 n# h* }- F# _& P( ^, O. G5 ~

3 O3 r7 r$ K( q单片机源程序如下:
' s1 r/ D% c% N( _' B
  • /*=============================================================*/
  • #include <reg52.H>                //器件配置文件
  • #include <intrins.h>
  • #include "lcd.h"
  • #define u8 unsigned char
  • #define u16 unsigned int
  • #define uchar unsigned char
  • #define uint unsigned int
  •                //一般选用500K
  • sbit DQ=P2^7; //ds18b20 与单片机连接口
  •                          //将短接片去掉开启位选功能,否则默认IN0为输入引脚
  • sbit motor=P1^0;//当湿度过低时。给高电平
  • sbit ledgreen=P1^1;//当温度过高时,打开风扇
  • sbit ledred=P1^2;   //温度低时,打开辅热
  • unsigned char AD_DATA[2]; //保存IN0通道转换后的数据
  • unsigned char disbuff[7] = { 0,0,0,0,};
  • unsigned char Disp[]="0123456789";         //使用字符串保存数字0~9所对应的ASCLL码
  • //unsigned char I_Disp[]="value: ";           //初始显示值
  • unsigned char i,tflag;
  • unsigned int a,voltage,circuit,electirc,aa,bb,cc,ab;
  • unsigned char dd,ee,ff,gg;
  • unsigned int tvalue,time,Level,High,t,ppm; // 温度值
  •         uint dat=0,shidu;
  • void delay_18b20(unsigned int i) // 延时 1 微秒
  • {
  •         while(i--);
  • }
  • void ds18b20rst() //ds18b20 初始化子函数
  • {
  •         unsigned charx=0;
  •         DQ = 1; // 信号线 DQ复位
  •         delay_18b20(4); // 延时
  •         DQ = 0; //DQ 拉低
  •         delay_18b20(100); // 精确延时大于 480us
  •         DQ = 1; // 拉高
  •         delay_18b20(40);
  • }
  • void ds18b20wr(unsigned char wdata) /* 写数据子函数 , 无返回值,含参数 */
  • {
  •         unsigned char i=0;
  •         for (i=8; i>0; i--)// 要写完一个字节,故需要重复 8 次以下操作
  •         {
  •                 DQ = 0; // 数据线拉低
  •                 DQ = wdata&0x01;// 按从低到高的顺序发送数据(一次发送一位 )
  •                 delay_18b20(10);
  •                 DQ = 1; // 最后将数据线拉高
  •                 wdata>>=1; // 将 wdata 右移 1 位
  •         }
  • }
  • unsigned char ds18b20rd() // 读数据子函数 , 是有返回值 dat
  • {
  •         unsigned char i=0;
  •         unsigned char dat = 0;
  •         for (i=8;i>0;i--)// 要读完一个字节,故需要重复 8 次以下操作
  •         {
  •                 DQ = 0; // 给脉冲信号
  •                 dat>>=1;
  •                 DQ = 1; // 给脉冲信号
  •                 if(DQ)
  •                         dat|=0x80;
  •                         delay_18b20(10);
  •         }
  •         return(dat); // 返回 dat
  • }
  • read_temp() // 读取温度值并转换的子函数,有返回值温度值 tvalue
  • {
  •         unsigned char a,b;
  •         ds18b20rst(); // 调用 ds18b20 初始化子函数
  •         ds18b20wr(0xcc);// 调用写数据子函数,向 ds18b20 写命令 0xcc
  •         //ccH 表示跳过 ROM读序列号,适用于单机工作,直接向 18b20 发送温度变换命令
  •         ds18b20wr(0x44);// 调用写数据子函数,向 ds18b20 写命令 0x44
  •         //44H 表示启动 ds18b20 温度转换 , 结果自行存入 9 字节的 RAM中
  •         ds18b20rst(); // 调用 ds18b20 初始化子函数
  •         ds18b20wr(0xcc);// 同上
  •         ds18b20wr(0xbe);// 调用写数据子函数,向 ds18b20 写命令 0xbe
  •         //beH 表示读取 RAM中 9 字节的温度数据
  •         a=ds18b20rd(); // 调用读数据子函数,并将所得数据给 a
  •         b=ds18b20rd(); //
  •         tvalue=b; // 把 b 的值给 tvalue
  •         tvalue<<=8; //tvalue 左移 8 位
  •         tvalue=tvalue|a;//tvalue 与 a 进行按位或
  •         if(tvalue<0x0fff)//
  •         tflag=0; // 前五位为 0 时,读取的温度为正,标志位为 0,此时只要
  •         else // 前五位为 1 时,读取的温度为负,标志位为 1,此时需要
  •         {                 // 将测得数值取反后再加 1,再乘以 0.0625 即可得到实际温度
  •         tvalue=~tvalue+1;
  •         tflag=1; // 此时表示负温度
  •         }
  •         tvalue=tvalue*(0.625);// 温度值扩大 10 倍,精确到 1 位小数
  •         return(tvalue); // 返回温度值
  • }
  • /***********************************
  • 函数名:  AD()
  • 功能:    启动AD转换将值储存于 AD_DATA[0]
  • ***********************************/
  • sbit ADCS         =P3^5;
  • sbit ADCLK  =P3^2;
  • sbit ADDI         =P3^3;
  • sbit ADDO         =P3^4;
  • unsigned int Adc0832(unsigned char channel)
  • {
  •         uchar i=0;
  •         uchar j;
  •         uchar ndat=0;
  •         uchar  Vot=0;
  •         if(channel==0)channel=2;
  •         if(channel==1)channel=3;
  •         ADDI=1;
  •         _nop_();
  •         _nop_();
  •         ADCS=0;//拉低CS端
  •         _nop_();
  •         _nop_();
  •         ADCLK=1;//拉高CLK端
  •         _nop_();
  •         _nop_();
  •         ADCLK=0;//拉低CLK端,形成下降沿1
  •         _nop_();
  •         _nop_();
  •         ADCLK=1;//拉高CLK端
  •         ADDI=channel&0x1;
  •         _nop_();
  •         _nop_();
  •         ADCLK=0;//拉低CLK端,形成下降沿2
  •         _nop_();
  •         _nop_();
  •         ADCLK=1;//拉高CLK端
  •         ADDI=(channel>>1)&0x1;
  •         _nop_();
  •         _nop_();
  •         ADCLK=0;//拉低CLK端,形成下降沿3
  •         ADDI=1;//控制命令结束
  •         _nop_();
  •         _nop_();
  •         dat=0;
  •         for(i=0;i<8;i++)
  •         {
  •                 dat|=ADDO;//收数据
  •                 ADCLK=1;
  •                 _nop_();
  •                 _nop_();
  •                 ADCLK=0;//形成一次时钟脉冲
  •                 _nop_();
  •                 _nop_();
  •                 dat<<=1;
  •                 if(i==7)dat|=ADDO;
  •         }
  •         for(i=0;i<8;i++)
  •         {
  •                 j=0;
  •                 j=j|ADDO;//收数据
  •                 ADCLK=1;
  •                 _nop_();
  •                 _nop_();
  •                 ADCLK=0;//形成一次时钟脉冲
  •                 _nop_();
  •                 _nop_();
  •                 j=j<<7;
  •                 ndat=ndat|j;
  •                 if(i<7)ndat>>=1;
  •         }
  •         ADCS=1;//拉低CS端
  •         ADCLK=0;//拉低CLK端
  •         ADDO=1;//拉高数据端,回到初始状态
  •         dat<<=8;
  •         dat|=ndat;
  •         return(dat);            //return ad data
  • }
  • void Conut(void)
  • {
  •                  circuit=dat/256;
  •         ppm=circuit;
  •         aa=ppm/1000;
  •          bb=ppm%1000/100;
  •         cc=ppm%100/10;
  •          ab=ppm%10;
  •         dd=tvalue/1000; // 百位数
  •         ee=tvalue%1000/100;// 十位数
  •         ff=tvalue%100/10 ;// 个位数
  •         gg=tvalue%10; // 小数位
  •         if(ppm>150)   //湿度大于150/256=58.59后电机停转
  •         {motor=0;}
  •         if(ppm<=80) //小于31.25%电机开始启动
  •         {motor=1;        }
  •         if(tvalue>400)  //温度大于40度风扇开始启动
  •         {ledgreen=1;ledred=0;}
  •         if(tvalue<=400)  //温度小于40度风扇关闭
  •         {ledgreen=0;ledred=1;}
  • }
  • /***********************************
  • 函数名:  delayms()
  • 功能:    延时 ms 毫秒
  • ***********************************/
  • void delayms(unsigned int ms)
  • {
  •         unsigned char j;
  •         i=100;
  •         for(;ms;ms--)
  •         {
  •                 while(--i)
  •                 {
  •                         j=10;
  •                         while(--j);
  •                 }
  •         }
  • }
  • /***********************************
  • 函数名:  LcdDisplay()
  • 功能:    用lcd显示数组disbuff[]中的值
  • ***********************************/
  • void LcdDisplay(void)
  • {
  •   LCD1602_write_com(0x80+1+0x40);
  •         LCD1602_write_word("c=");
  •         LCD1602_write_com(0x80+3+0x40);
  •         LCD1602_write_data(0x30+aa);
  •         LCD1602_write_com(0x80+4+0x40);
  •         LCD1602_write_data(0x30+bb);
  •   LCD1602_write_com(0x80+5+0x40);
  •         LCD1602_write_data(0x30+cc);
  •         LCD1602_write_com(0x80+6+0x40);
  •         LCD1602_write_data(0x30+ab);
  •         LCD1602_write_com(0x80+7+0x40);
  •         LCD1602_write_word("humid");
  •         LCD1602_write_com(0x80+1);
  •         LCD1602_write_word("tem=");
  •         LCD1602_write_com(0x80+5);
  •         LCD1602_write_data(0x30+dd);
  •         LCD1602_write_com(0x80+8);
  •         LCD1602_write_word(".");
  •   LCD1602_write_com(0x80+6);
  •         LCD1602_write_data(0x30+ee);
  •         LCD1602_write_com(0x80+7);
  •         LCD1602_write_data(0x30+ff);
  •         LCD1602_write_com(0x80+9);
  •         LCD1602_write_data(0x30+gg);
  • }
  • /***********************************
  • 函数名:  Analog_IO_Sel()
  • 参数说明: m 的值对应ADC0809芯片上模拟输入的IO
  • 功能:    确定模拟输入位选
  • ***********************************/
  • //void init()
  • //{if(a==0)
  • //{
  • //          EA=1; //开总中断
  • //    TMOD=0x02; //设定定时器 T0工作方式
  • //    TH0=21; //利用T0中断产生CLK信号
  • //    TL0=21;
  • ……………………
  • # ~$ O, Z2 q; r0 r

0 h* N4 n4 A3 J1 @+ t3 Z
8 b6 N- i+ R) ?. C9 K& T
6 }2 X5 s3 v" A1 A; A
4 v5 @  Z" H  P+ S( b

该用户从未签到

2#
发表于 2022-6-22 10:13 | 只看该作者
大佬那个温度怎么改才能让他一下加减没那么多, E) ^, y* b- _9 |
还有用ADC0832可以检测湿度吗,不是应该用湿度传感器吗

该用户从未签到

3#
发表于 2022-6-22 11:17 | 只看该作者
大棚内CO2 浓度也是一项重要指标,没有CO2,作物就不会生长。智能大棚必须要有CO2自动调节功能。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

推荐内容上一条 /1 下一条

EDA365公众号

关于我们|手机版|EDA365电子论坛网 ( 粤ICP备18020198号-1 )

GMT+8, 2025-6-7 03:06 , Processed in 0.078125 second(s), 23 queries , Gzip On.

深圳市墨知创新科技有限公司

地址:深圳市南山区科技生态园2栋A座805 电话:19926409050

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