找回密码
 立即注册

QQ登录

只需一步,快速开始

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

4个继电器的DTH11温湿度控制器 单片机程序与Proteus仿真

  [复制链接]
跳转到指定楼层
楼主
根据DTH11传感器来记录温湿度数据,并以此来控制4个不同的继电器,达到控制不同负载来调节温湿度的目的

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


制作出来的实物图如下:


单片机源程序如下:
  1. #include <reg52.h>
  2. #include <intrins.h>
  3. #include <absacc.h>
  4. #include <math.h>                           //包含头文件
  5.   
  6. #define uchar unsigned char
  7. #define uint unsigned int           //宏定义

  8. //定义四个输出端口
  9. sbit Led_jiashi=P3^6;                //加湿
  10. sbit Led_qushi=P3^4;                //去湿
  11. sbit Led_jiangwen=P3^2;                //降温
  12. sbit Led_shengwen=P3^3;                //升温
  13. //定义三个设置按键
  14. sbit Key_SET = P2^0;                //设置按键
  15. sbit Key_ADD = P2^1;                //加按键
  16. sbit Key_SUB = P2^2;                //减按键
  17. sbit Key_OK  = P2^3;                //确定按键
  18. //定义24C02数据口
  19. sbit SCL = P1^0;
  20. sbit SDA = P1^1;
  21. //定义DHT11数据口
  22. sbit DATA = P1^7;
  23. sbit buzz=P3^5;                                //蜂鸣器接口

  24. //定义LCD1602端口
  25. sbit E=P1^3;                //1602使能引脚
  26. //sbit RW=P2^6;                //1602读写引脚         我们只需要向液晶里写数据,不需要读取数据,所以就把读写引脚直接接地,程序里就不用单独控制了
  27. sbit RS=P1^2;                //1602数据/命令选择引脚
  28. //定义全局变量
  29. uchar U8FLAG,U8temp,U8comdata,U8RH_data_H_temp,U8RH_data_L_temp,U8T_data_H_temp,U8T_data_L_temp,U8checkdata_temp;        //定义读取温湿度变量
  30. uchar U8RH_data_H,U8RH_data_L,U8T_data_H,U8T_data_L,U8checkdata;
  31. uchar Mode,humidity,temperature;                                                                                                                                                                        //设置模式、读取到的湿度温度数据存储变量
  32. char TH,TL,HH,HL;                                                                                                                                                                                                        //温湿度的上下限变量
  33. bit bdata FlagStartRH,hot,cold,humid,dry,BJ;                                                                                                                                                //开启转换温湿度标志位、热冷湿干和报警变量

  34. //定时器0初始化
  35. void Timer0_Init()
  36. {
  37.         ET0 = 1;        //允许定时器0中断
  38.         TMOD = 0x11;       //定时器工作方式选择
  39.         TL0 = 0xb0;     
  40.         TH0 = 0x3c;     //定时器赋予初值50ms
  41.         TR0 = 1;        //启动定时器T0
  42. }

  43. //定时器0中断
  44. void Timer0_ISR (void) interrupt 1 using 0
  45. {
  46.         uchar RHCounter;                                 //定义计数变量
  47.         TL0 = 0xb0;
  48.         TH0 = 0x3c;     //定时器赋予初值
  49.         RHCounter++;                                         //每进一次中断就是50ms,此变量加一
  50.         if(RHCounter%10==0&&BJ==1)                 //加到10的整数倍,并且报警标志位为1
  51.         buzz=!buzz;                                                 //开启报警,每500ms蜂鸣器引脚取反一次,就是蜂鸣器一秒响一次
  52.         else if(BJ==0)                                         //报警标志位为0时
  53.         buzz=1;                                                         //关闭报警
  54.         //每2秒钟启动一次温湿度转换
  55.     if (RHCounter >= 40)                         //计数到40次,就是2s,启动一次温湿度转换
  56.     {
  57.        FlagStartRH = 1;                                 //启动转换变量置1
  58.            RHCounter = 0;                                 //计数变量清零
  59.     }
  60. }

  61. /*以下程序为24c02的程序,都是官方的实例程序,可以参考时序图理解,都是固定的*/

  62. /*********************************
  63.       BASE  DRIVE
  64. **********************************/
  65. void DELAY(unsigned int t)                          //延时函数
  66. {
  67.         while(t!=0)
  68.         t--;
  69. }

  70. /******************************
  71.       IIC  DRIVE
  72. ******************************/
  73. void IICStart(void)                                         //24c02的开始函数,关于24c02的函数多看下24c02的手册
  74. {
  75.      SCL=0;                                                   //SCL引脚拉低
  76.           DELAY(1);                                                 //短延时
  77.      SDA=1; SCL=1; DELAY(1);                 //SDA拉高,SCL拉高,短延时
  78.      SDA=0; DELAY(1);                                 //SDA拉低,短延时
  79.      SCL=0;                                                  //SCL拉低
  80. }

  81. void IICStop(void)                                         //停止
  82. {
  83.          SDA=0;SCL=1; DELAY(1);                         //注释略
  84.      SDA=1; DELAY(1);
  85.      SCL=0;         
  86. }
  87. void SEND0(void)                                         //发送
  88. {
  89.         SDA=0;
  90.         SCL=1;
  91.         DELAY(1);
  92.         SCL=0;
  93. }

  94. void SEND1(void)
  95. {
  96.         SDA=1;
  97.         DELAY(1);
  98.         SCL=1;
  99.         DELAY(1);
  100.         SCL=0;
  101. }

  102. bit Check_Ack(void)                                                //应答
  103. {
  104.         unsigned char errtime=250;                        //定义变量
  105.         DELAY(1);                                                
  106.         SCL=1;
  107.         DELAY(1);
  108.         CY=SDA;                                                                //SDA引脚高电平就是1,低电平就是0,赋值给CY
  109.         while(CY)                                                        //如果CY为1,就执行此while
  110.         {
  111.                 errtime--;                                                 //变量减
  112.                 CY=SDA;                                                        //赋值
  113.                 if (!errtime)                                        //判断有没有减到0
  114.                 {
  115.                         IICStop();                                        //停止24C02
  116.                         return 1;                                        //返回1
  117.                 }
  118.         }
  119.         DELAY(1);
  120.         SCL=0;
  121.         return 0;
  122. }

  123. void Write_byte(unsigned char dat)
  124. {
  125.     unsigned char i;
  126.         for(i=0;i<8;i++)
  127.         {        
  128.                 if((dat<<i)&0x80)
  129.                 SEND1();
  130.                 else
  131.                 SEND0();
  132.         }
  133. }

  134. unsigned char Read_byte(void)
  135. {
  136.         unsigned char i,temp=0;     
  137.         for(i=0;i<8;i++)
  138.         {
  139.         SDA=1;
  140.             SCL=1;
  141.             DELAY(1);  
  142.                 if(SDA==1)
  143.                 {
  144.                         temp=temp<<1;
  145.                         temp=temp|0x01;
  146.                 }
  147.                 else
  148.                 temp=temp<<1;
  149.                  SCL=0;        
  150.           }
  151.           return temp;
  152. }

  153. /************************************
  154.       EEPROM  DRIVE
  155.           Addr:from 0x00-->
  156. *************************************/
  157. unsigned char rdeeprom(unsigned char addr)
  158. {
  159.         unsigned char temp=0;
  160.                 bit flag=0;
  161.                 IICStart();
  162.                 Write_byte(0xa0);
  163.         Check_Ack();
  164.                 Write_byte(addr);
  165.                 Check_Ack();
  166.                 IICStart();
  167.                 Write_byte(0xa1);
  168.                 Check_Ack();
  169.                 temp=Read_byte();
  170.                 SEND1();
  171.                 IICStop();
  172.              return temp;   
  173. }  
  174.    
  175.    
  176. void wrteeprom(unsigned char addr,unsigned char dat)
  177. {
  178.                IICStart();
  179.                 Write_byte(0xa0);
  180.                 Check_Ack();
  181.                 Write_byte(addr);
  182.                 Check_Ack();
  183.                 Write_byte(dat);
  184.                 Check_Ack();
  185.                 IICStop();
  186. }

  187. /*以下程序为DHT11温湿度传感器程序,官方的实例程序*/


  188. void Delay1(uint j)                        //延时程序
  189. {
  190.     uchar i;
  191.     for(;j>0;j--)
  192.     {         
  193.                 for(i=0;i<27;i++);
  194.     }
  195. }

  196. void  Delay_10us(void)                  //延时函数,大约10us,不精确
  197. {
  198.     uchar i;
  199.     i--;
  200.     i--;
  201.     i--;
  202.     i--;
  203.     i--;
  204.     i--;
  205. }        

  206. void  COM(void)                                                                         //读取温湿度函数
  207. {
  208.     uchar i;
  209.     for(i=0;i<8;i++)           
  210.     {
  211.               U8FLAG=2;
  212.                    while((!DATA)&&U8FLAG++);
  213.                 Delay_10us();
  214.                 Delay_10us();
  215.                 Delay_10us();
  216.                   U8temp=0;
  217.         if(DATA)U8temp=1;
  218.                     U8FLAG=2;
  219.                 while((DATA)&&U8FLAG++);
  220.                    //超时则跳出for循环                  
  221.                    if(U8FLAG==1)break;
  222.                    //判断数据位是0还是1         
  223.                      
  224.                 // 如果高电平高过预定0高电平值则数据位为 1
  225.                     
  226.                 U8comdata<<=1;
  227.                    U8comdata|=U8temp;        //0
  228.     }//rof
  229. }

  230. //--------------------------------
  231. //-----温湿度读取子程序 ------------
  232. //--------------------------------
  233. //----以下变量均为全局变量--------
  234. //----温度高8位== U8T_data_H------
  235. //----温度低8位== U8T_data_L------
  236. //----湿度高8位== U8RH_data_H-----
  237. //----湿度低8位== U8RH_data_L-----
  238. //----校验 8位 == U8checkdata-----
  239. //----调用相关子程序如下----------
  240. //---- Delay();, Delay_10us();,COM();
  241. //--------------------------------
  242. uchar RH(void)
  243. {
  244.     //主机拉低18ms
  245.     DATA=0;
  246.         Delay1(180);  //原来为5
  247.         DATA=1;
  248.         //总线由上拉电阻拉高 主机延时20us
  249.         Delay_10us();
  250.         Delay_10us();
  251.         Delay_10us();
  252.         Delay_10us();
  253.         //主机设为输入 判断从机响应信号
  254.         DATA=1;
  255.         //判断从机是否有低电平响应信号 如不响应则跳出,响应则向下运行         
  256.         if(!DATA)                 //T !         
  257.         {
  258.             U8FLAG=2;
  259.             //判断从机是否发出 80us 的低电平响应信号是否结束         
  260.             while((!DATA)&&U8FLAG++);
  261.             U8FLAG=2;
  262.             //判断从机是否发出 80us 的高电平,如发出则进入数据接收状态
  263.             while((DATA)&&U8FLAG++);
  264.             //数据接收状态                 
  265.             COM();
  266.             U8RH_data_H_temp=U8comdata;
  267.             COM();
  268.             U8RH_data_L_temp=U8comdata;
  269.             COM();
  270.             U8T_data_H_temp=U8comdata;
  271.             COM();
  272.             U8T_data_L_temp=U8comdata;
  273.             COM();
  274.             U8checkdata_temp=U8comdata;
  275.             DATA=1;
  276.             //数据校验
  277.             U8temp=(U8T_data_H_temp+U8T_data_L_temp+U8RH_data_H_temp+U8RH_data_L_temp);
  278.             if(U8temp==U8checkdata_temp)
  279.             {
  280.                       U8RH_data_H=U8RH_data_H_temp;
  281.                       U8RH_data_L=U8RH_data_L_temp;
  282.                       U8T_data_H=U8T_data_H_temp;
  283.                       U8T_data_L=U8T_data_L_temp;
  284.                       U8checkdata=U8checkdata_temp;
  285.             }
  286.                 return 1;
  287.         }
  288.         else   //传感器不响应
  289.         {
  290.            return 0;
  291.         }
  292. }

  293. /********************************************************************
  294. * 文件名  : 液晶1602显示.c
  295. * 描述    :  该程序实现了对液晶1602的控制。
  296. ***********************************************************************/


  297. /********************************************************************
  298. * 名称 : delay()
  299. * 功能 : 延时,延时时间大概为140US。
  300. * 输入 : 无
  301. * 输出 : 无
  302. ***********************************************************************/

  303. void delay()                                                         
  304. {
  305.         int i,j;
  306.         for(i=0; i<=10; i++)
  307.         for(j=0; j<=2; j++);
  308. }         
  309.         
  310. /********************************************************************
  311. * 名称 : enable(uchar del)
  312. * 功能 : 1602命令函数
  313. * 输入 : 输入的命令值
  314. * 输出 : 无
  315. ***********************************************************************/

  316. void enable(uchar del)
  317. {
  318.         P0 = del;                                          //数据发送到P0口
  319.         RS = 0;                                                  //RS引脚拉低
  320.         E = 1;                                                  //E引脚高电平
  321.         delay();                                          //延时
  322.         E = 0;                                                  //E引脚低电平
  323.         delay();                                          //延时
  324. }

  325. /********************************************************************
  326. * 名称 : write(uchar del)
  327. * 功能 : 1602写数据函数
  328. * 输入 : 需要写入1602的数据
  329. * 输出 : 无
  330. ***********************************************************************/

  331. void write(uchar del)
  332. {
  333.         P0 = del;                                           //同上
  334.         RS = 1;
  335.         E = 1;
  336.         delay();
  337.         E = 0;
  338.         delay();
  339. }

  340. /********************************************************************
  341. * 名称 : L1602_init()
  342. * 功能 : 1602初始化,请参考1602的资料
  343. * 输入 : 无
  344. * 输出 : 无
  345. ***********************************************************************/
  346. void L1602_init(void)
  347. {
  348.         
  349.         enable(0x38);                  //设置液晶工作模式,意思:16*2行显示,5*7点阵,8位数据
  350.         enable(0x0c);                  //开显示不显示光标
  351.         enable(0x06);                   //整屏不移动,光标自动右移
  352.         enable(0x01);         //清屏
  353. }

  354. /********************************************************************
  355. * 名称 : L1602_char(uchar hang,uchar lie,char sign)
  356. * 功能 : 改变液晶中某位的值,如果要让第一行,第五个字符显示"b" ,调用该函数如下
  357.                  L1602_char(1,5,'b')
  358. * 输入 : 行,列,需要输入1602的数据
  359. * 输出 : 无
  360. ***********************************************************************/
  361. void L1602_char(uchar hang,uchar lie,char sign)
  362. {
  363.         uchar a;                                                                         //定义变量
  364.         if(hang == 1) a = 0x80;                                                 //如果hang变量为1,让地址数据为0x80就是第一行的
  365.         if(hang == 2) a = 0xc0;                                                 //如果hang变量为0,让地址数据为0xc0就是第二行的
  366.         a = a + lie - 1;                                                         //列数据减一,因为液晶屏的列是从0开始的
  367.         enable(a);                                                                         //发送行和列数据
  368.         write(sign);                                                                 //写显示内容
  369. }

  370. /********************************************************************
  371. * 名称 : L1602_string(uchar hang,uchar lie,uchar *p)
  372. * 功能 : 改变液晶中某位的值,如果要让第一行,第五个字符开始显示"ab cd ef" ,调用该函数如下
  373.                   L1602_string(1,5,"ab cd ef;")
  374. * 输入 : 行,列,需要输入1602的数据
  375. * 输出 : 无
  376. ***********************************************************************/
  377. void L1602_string(uchar hang,uchar lie,uchar *p)
  378. {
  379.         uchar a;
  380.         if(hang == 1) a = 0x80;                                 //第一行地址
  381.         if(hang == 2) a = 0xc0;                                 //第二行地址
  382.         a = a + lie - 1;                                         //行和列数据加一起
  383.         enable(a);                                                         //发送行列数据
  384.         while(1)                                                         //进入循环
  385.         {
  386.                 if(*p == '\0') break;                         //发送完字符串后跳出while循环
  387.                 write(*p);                                                 //没发送完就继续发
  388.                 p++;                                                         //字符串指针地址加1
  389.         }
  390. }

  391. //显示整型的温湿度数据用,共占用4位,其中一位符号位
  392. void L1602_int(uchar hang, uchar lie, int num)
  393. {
  394.    uint temp;
  395.    uint gewei,shiwei,baiwei,sign;
  396.    if (num >= 0)                                                         //如果温度值大于等于0
  397.    sign = 0;                                                                 //符号为正
  398.    else                                                                                 //反之
  399.    sign = 1;                                                                 //符号为负
  400.    temp = abs(num);                                                         //温度值取绝对值
  401.    baiwei = temp / 100;                                                 //除以100得到温度值百位
  402.    temp = temp - baiwei*100;                                 //温度值减去百位得到十位和个位的数
  403.    shiwei = temp / 10;                                                 //除以10得到十位的数据
  404.    gewei = temp - shiwei*10;                                 //减去十位的数据得到个位的数
  405.    num = abs(num);                                                         //温度取绝对值
  406.    if (num>=100)                                                         //如果温度大于100
  407.    {
  408.    //   L1602_char(hang, lie+1, baiwei+48);  
  409.           L1602_char(hang, lie+2, shiwei+48);           //显示十位和个位
  410.           L1602_char(hang, lie+3, gewei+48);  
  411.    }
  412.    else if (num>=10)                                                 //温度大于10
  413.    {
  414.       if (sign == 1)                                                    //负数时
  415.           L1602_char(hang, lie+1, '-');                         //显示负号
  416.           L1602_char(hang, lie+2, shiwei+48);           //显示十位和个位数
  417.       L1602_char(hang, lie+3, gewei+48);
  418.    }
  419.    else                                                                                 //温度小于10
  420.    {
  421.       if (sign == 1)                                                    //负数时
  422.           L1602_char(hang, lie+2, '-');                         //显示负号
  423.           else                                                                         //正数
  424.           L1602_char(hang, lie+2, ' ');                         //十位不显示
  425.       L1602_char(hang, lie+3, gewei+48);           //显示个位数
  426.    }
  427. }

  428. void display()                                                                                         //显示函数
  429. {                                                                                                                 
  430.         if(Mode==0)                                                                                         //不是设置状态
  431.         {
  432.                 L1602_int(1,3,temperature);                                                 //显示温度数据
  433.                 L1602_char(1,7,0xdf);                                                         //显示摄氏度的°
  434.                 L1602_int(1,12,humidity);                                                  //显示湿度数据

  435.                 if(hot==1&&cold==0&&humid==0&&dry==0)                         //温度过高
  436.                 {L1602_string(2,1," It's very hot! ");BJ=1;}          //显示热 ,报警
  437.                 else if(hot==1&&cold==0&&humid==1&&dry==0)                 //温度高,湿度高
  438.                 {L1602_string(2,1," Hot and humid! ");BJ=1;}         //显示热 ,湿, 报警
  439.                 else if(hot==1&&cold==0&&humid==0&&dry==1)                 //温度高 ,湿度低
  440.                 {L1602_string(2,1,"  Hot and dry!  ");BJ=1;}         //显示热 ,干, 报警
  441.                 else if(hot==0&&cold==1&&humid==0&&dry==0)                 //温度低
  442.                 {L1602_string(2,1," It's very cold!");BJ=1;}         //显示冷 ,报警
  443.                 else if(hot==0&&cold==1&&humid==1&&dry==0)                 //温度低 ,湿度高
  444.                 {L1602_string(2,1," Cold and humid!");BJ=1;}         //显示冷 ,湿,报警
  445.                 else if(hot==0&&cold==1&&humid==0&&dry==1)                 //温度低 ,湿度低
  446.                 {L1602_string(2,1,"  Cold and dry! ");BJ=1;}         //显示冷 ,干,报警
  447.                 else if(hot==0&&cold==0&&humid==1&&dry==0)                 //湿度高
  448.                 {L1602_string(2,1,"It's very humid!");BJ=1;}         //显示潮湿,报警
  449.                 else if(hot==0&&cold==0&&humid==0&&dry==1)                 //湿度低
  450.                 {L1602_string(2,1," It's very dry! ");BJ=1;}         //显示干燥
  451.                 else if(hot==0&&cold==0&&humid==0&&dry==0)                 //都在范围内
  452.                 {L1602_string(2,1,"Good environment");BJ=0;}         //显示环境好,关闭报警
  453.         }                                                                          
  454. }

  455. /***按键函数***/
  456. void KEY()                                                                                                 //按键函数
  457. {
  458.         if(Key_SET==0)                                                                                 //设置按键按下
  459.         {
  460.                 Delay1(200);                                                                         //延时去抖
  461.                 if(Key_SET==0)                                                                         //再次判断按键按下
  462.                 {
  463.                         Mode++;                                                                                 //显示位加
  464.                         TR0=0;                                                                                 //关闭定时器
  465.                         Led_shengwen=1;
  466.                         Led_jiangwen=1;
  467.                         Led_jiashi=1;
  468.                         Led_qushi=1;                                                                 //关闭四路继电器输出
  469.                         hot=0;
  470.                         cold=0;
  471.                         humid=0;
  472.                         dry=0;                                                                                 //变量清零
  473.                         if(Mode==1)                                                                         //设置第一个位置
  474.                         {
  475.                                 L1602_string(1,1," TH:    C HH:  %");         //初始化设置界面,第一行显示温度和湿度上限
  476.                                 L1602_char(1,8,0xdf);                                         //显示摄氏度的°
  477.                                 L1602_string(2,1," TL:    C HL:  %");         //第二行显示温度和湿度的下限
  478.                                 L1602_char(2,8,0xdf);                                         //显示摄氏度的°
  479.                                 L1602_int(1,4,TH);                                                 //显示温度上限
  480.                                 L1602_int(1,12,HH);                                                 //显示湿度上限
  481.                                 L1602_int(2,4,TL);                                                 //显示温度下限
  482.                                 L1602_int(2,12,HL);                                                 //显示湿度下限
  483.                                 enable(0x80+6);                                                         //选中第一个位置闪烁
  484.                                 enable(0x0f);                                                         //开启闪烁
  485.                         }
  486.                         else if(Mode==2)                                                         //第二个位置
  487.                         {
  488.                                 enable(0x80+0x40+6);                                         //温度上限位置闪烁
  489.                                 enable(0x0f);
  490.                         }
  491.                         else if(Mode==3)
  492.                         {
  493.                                 enable(0x80+14);                                                 //湿度上限位置闪烁
  494.                                 enable(0x0f);
  495.                         }
  496.                         else if(Mode==4)
  497.                         {
  498.                                 enable(0x80+0x40+14);                                         //湿度下限位置闪烁
  499.                                 enable(0x0f);
  500.                         }
  501.                         else if(Mode>=5)                                                         //设置完最后一位,回到第一位
  502.                         {
  503.                                 Mode=1;                                                                         //回到第一位置
  504.                                 enable(0x80+6);                                                         //第一个位置闪烁
  505.                                 enable(0x0f);
  506.                         }
  507.                         while(!Key_SET);                                                         //按键释放
  508.                 }
  509.         }
  510.         else if(Key_ADD==0)                                                                         //加按键
  511.         {
  512.                 Delay1(200);
  513.                 if(Key_ADD==0)
  514.                 {
  515.                         if(Mode==1)                                                                         //设置温度上限
  516.                         {
  517.                                 TH++;                                                                         //温度上限加
  518.                                 if(TH>=100)                                                                 //加到100
  519.                                 TH=99;                                                                         //赋值99,也就是最大能加到99
  520.                                 L1602_int(1,4,TH);                                                 //显示温度上限
  521.                                 enable(0x80+6);                                                         //因为送显示数据了,闪烁的位置会自动右移,所以这里要指定要闪烁的位置
  522.                                 wrteeprom(0,TH);                                                 //将上限值写入AT24C02芯片
  523.                         }
  524.                         else if(Mode==2)                                                         //设置温度下限
  525.                         {
  526.                                 TL++;                                                                         //加
  527.                                 if(TL>=TH)                                                                 //下限不能比上限高
  528.                                 TL=TH-1;                                                                 //下限只能加到比上限小一
  529.                                 L1602_int(2,4,TL);                                                 //下面注释同上,略
  530.                                 enable(0x80+0x40+6);
  531.                                 wrteeprom(1,TL);
  532.                         }
  533.                         else if(Mode==3)
  534.                         {
  535.                                 HH++;
  536.                                 if(HH>=100)
  537.                                 HH=99;
  538.                                 L1602_int(1,12,HH);
  539.                                 enable(0x80+14);
  540.                                 wrteeprom(2,HH);
  541.                         }
  542.                         else if(Mode==4)
  543.                         {
  544.                                 HL++;
  545.                                 if(HL>=HH)
  546.                                 HL=HH-1;
  547.                                 L1602_int(2,12,HL);
  548.                                 enable(0x80+0x40+14);
  549.                                 wrteeprom(3,HL);
  550.                         }
  551.                         while(!Key_ADD);
  552.                 }
  553.         }
  554.         else if(Key_SUB==0)                                                        //减按键
  555.         {
  556.                 Delay1(200);
  557.                 if(Key_SUB==0)
  558.                 {
  559.                         if(Mode==1)
  560.                         {
  561.                                 TH--;
  562.                                 if(TH<=TL)
  563.                                 TH=TL+1;
  564.                                 L1602_int(1,4,TH);
  565.                                 enable(0x80+6);
  566.                                 wrteeprom(0,TH);
  567.                         }
  568.                         else if(Mode==2)
  569.                         {
  570.                                 TL--;
  571.                                 if(TL<=0)
  572.                                 TL=0;
  573.                                 L1602_int(2,4,TL);
  574.                                 enable(0x80+0x40+6);
  575.                                 wrteeprom(1,TL);
  576.                         }
  577.                         else if(Mode==3)
  578.                         {
  579.                                 HH--;
  580.                                 if(HH<=HL)
  581.                                 HH=HL+1;
  582.                                 L1602_int(1,12,HH);
  583.                                 enable(0x80+14);
  584.                                 wrteeprom(2,HH);
  585.                         }
  586.                         else if(Mode==4)
  587.                         {
  588.                                 HL--;
  589.                                 if(HL<=0)
  590.                                 HL=0;
  591.                                 L1602_int(2,12,HL);
  592.                                 enable(0x80+0x40+14);
  593.                                 wrteeprom(3,HL);
  594.                         }
  595.                         while(!Key_SUB);
  596.                 }
  597.         }
  598.         if(Key_OK==0&&Mode!=0)                                                        //确认按键
  599.         {
  600.                 Delay1(200);
  601.                 if(Key_OK==0)
  602.                 {
  603.                         L1602_string(1,1,"Tem:   C Hum:  %");         //退出设置状态,恢复待机显示界面
  604.                         L1602_string(2,1,"Good environment");
  605.                         Mode=0;                                                                        //清零
  606.                         TR0=1;                                                                        //打开定时器
  607.                         enable(0x0c);                                                        //光标不闪烁
  608.                         while(Key_OK==0);                                                //按键释放
  609.                 }
  610.         }
  611. }

  612. //数据初始化
  613. void Data_Init()
  614. {
  615.    Led_qushi = 1;
  616.    Led_jiashi=1;
  617.    Led_jiangwen = 1;
  618.    Led_shengwen = 1;                                //熄灭四个继电器
  619. }

  620. /********************************************************************
  621. * 名称 : Main()
  622. * 功能 : 主函数
  623. ***********************************************************************/
  624. void main()
  625. {
  626.     uint i, j, testnum;

  627.     EA = 0;                                                 //关闭定时器

  628.         Timer0_Init();  //定时器0初始化

  629.     Data_Init();                                        //数据初始化
  630.         EA = 1;                                                        //打开定时器

  631.         L1602_init();                                                         //液晶屏初始化
  632.         L1602_string(1,1," Welcome to T&H ");
  633.         L1602_string(2,1," Control System!");         //开机显示界面
  634.         //延时
  635.         for (i=0;i<1000;i++)                                         //延时
  636.            for (j=0;j<100;j++)
  637.            {;}
  638.             /***载入温度上限和湿度上限设定值***/
  639.         TH=rdeeprom(0);          //从AT24C02读取温度上限数据
  640.         Delay1(20);                 //加延时可以存取稳定
  641.         TL=rdeeprom(1);         //温度下限
  642.         Delay1(20);
  643.         HH=rdeeprom(2);         //湿度上限
  644.         Delay1(20);
  645.         HL=rdeeprom(3);         //湿度下限
  646.         Delay1(20);
  647.                  
  648.         if(TH<=0&&TL<=0&&HH<=0&&HL<=0) //如果是新单片机,温湿度数据都是小于0
  649.         {
  650.                 wrteeprom(0,30);                                         //那么就给温湿度的报警值赋初值,30  20  60  50
  651.                 Delay1(20);                 //加延时可以存取稳定
  652.                 TH=rdeeprom(0);                                                  //写进去再读出来
  653.                 Delay1(20);                 //加延时可以存取稳定

  654.                 wrteeprom(1,20);
  655.                 Delay1(20);                 //加延时可以存取稳定
  656.                 TL=rdeeprom(1);
  657.                 Delay1(20);                 //加延时可以存取稳定

  658.                 wrteeprom(2,60);
  659.                 Delay1(20);                 //加延时可以存取稳定
  660.                 HH=rdeeprom(2);
  661.                 Delay1(20);                 //加延时可以存取稳定

  662.                 wrteeprom(3,50);
  663.                 Delay1(20);                 //加延时可以存取稳定
  664.                 HL=rdeeprom(3);
  665.         }
  666.     //清屏
  667.         L1602_string(1,1,"                ");
  668.         L1602_string(2,1,"                ");
  669.     L1602_string(1,1,"Tem:   C Hum:  %");
  670.         L1602_string(2,1,"Good environment");         //显示待机界面
  671.    
  672.         while(1)                                                                 //进入while循环
  673.         {
  674.       
  675.                  if (FlagStartRH == 1)         //温湿度转换标志检查
  676.                  {
  677.                      TR0 = 0;                                                 //关闭定时器
  678.              testnum = RH();                                 //读取温湿度
  679.                           FlagStartRH = 0;                                 //转换标志清零
  680.                          TR0 = 1;                                                 //打开定时器
  681.                          humidity = U8RH_data_H;         //读出湿度,只取整数部分
  682.                          temperature = U8T_data_H;          //读出温度

  683.                         
  684.                          if(Mode==0)                //温湿度控制
  685.                          {
  686.                                  if (temperature > TH)                 //温度大于上限
  687.                                 {
  688.                                         Led_jiangwen = 0;                 //控制降温继电器打开
  689.                                         hot=1;                                         //温度高变量置1
  690.                                         Led_shengwen = 1;                 //升温继电器关闭
  691.                                         cold=0;                                         //温度低变量置0
  692.                         //                BJ=1;
  693.                                 }
  694.                                 else if(temperature<TL)                  //注释同上,略
  695.                                 {
  696.                                         Led_shengwen = 0;
  697.                                         cold=1;
  698.                                         Led_jiangwen = 1;
  699.                                         hot=0;
  700.                                         buzz=0;
  701.                         //                BJ=1;
  702.                                 }                              
  703.                                 else                                 //温度上下都不超限
  704.                                 {
  705.                                         Led_jiangwen=1;
  706.                                         Led_shengwen=1;
  707.                                         hot=0;
  708.                                         cold=0;
  709.                                         buzz=1;
  710.                                 }
  711.                                 if (humidity > HH)
  712.                                 {
  713.                                         Led_qushi = 0;
  714.                                         humid=1;
  715.                                         Led_jiashi = 1;
  716.                                         dry=0;
  717.                         //                BJ=1;
  718.                                 }
  719.                                 else if(humidity<HL)
  720.                                 {
  721.                                         Led_jiashi = 0;
  722.                                         dry=1;
  723.                                         Led_qushi = 1;
  724.                                         humid=0;
  725.                         //                BJ=1;
  726.                                 }               
  727.                                 else                                          //湿度上限都不超限
  728.                                 {
  729.                                         Led_qushi=1;
  730.                                         Led_jiashi=1;
  731.                                         humid=0;
  732.                                         dry=0;
  733.                                 }        
  734.                          }
  735.                          else                                          //所有数据都不超限
  736.                          {
  737.                                  Led_shengwen=1;
  738.                                 Led_jiangwen=1;
  739.                                 Led_jiashi=1;
  740.                                 Led_qushi=1;                  //关闭所有继电器
  741.                                 hot=0;
  742.                                 cold=0;
  743.                                 humid=0;
  744.                                 dry=0;                                   //变量清零
  745.                                 BJ=0;                                   //关闭报警
  746.                          }        
  747.                 }
  748.                 display();                                                //调用显示函数
  749.                 KEY();                                                        //调用按键扫描函数
  750.         }        
  751. }
复制代码

所有资料51hei提供下载(Proteus7.5版本的仿真+程序):
4个继电器的温湿度控制器.7z (424.6 KB, 下载次数: 171)

评分

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

查看全部评分

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

使用道具 举报

沙发
ID:89286 发表于 2021-3-9 04:42 | 只看该作者
thanks for sharing
回复

使用道具 举报

板凳
ID:582255 发表于 2021-3-15 14:58 | 只看该作者
5v的继电器驱动没问题吧?
回复

使用道具 举报

地板
ID:922803 发表于 2021-6-6 10:11 | 只看该作者
需要用Proteus7.5版本打开才能显示
回复

使用道具 举报

5#
ID:961300 发表于 2021-9-25 19:57 | 只看该作者
楼主,照着做了一个,为什么不显示温度和湿度,只显示0%
回复

使用道具 举报

6#
ID:961300 发表于 2021-9-25 21:15 | 只看该作者
楼主能帮忙看看什么问题吗?
回复

使用道具 举报

7#
ID:990300 发表于 2021-12-12 21:49 | 只看该作者
我想问一下那个蜂鸣器仿真时为什么不会响啊,还有那个蜂鸣器为什么要加一个开关啊?求解答
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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