找回密码
 立即注册

QQ登录

只需一步,快速开始

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

单片机智能热水器设计方案 含仿真与源码及视频讲解

  [复制链接]
跳转到指定楼层
楼主
这是我设计的智能热水器的控制方案基本功能:将水温控制在一个0到99摄氏度的温度上,同时还具有无水自动加水,水满停止加水以及延时和红外控制的功能。
里面包含:
1源代码
2器件清单
3系统仿真
单片机智能热水器仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)


仿真视频讲解:




单片机源程序如下:
  1. //程序头函数
  2. #include <reg52.h>
  3. //显示函数
  4. #include <display.h>
  5. //宏定义
  6. #define uint unsigned int
  7. #define uchar unsigned char

  8. //管脚声明
  9. sbit jdq= P1^0;        //加热继电器
  10. sbit shui=P1^3;//加水继电器
  11. sbit Feng = P2^6; //蜂鸣器
  12. //按键
  13. sbit Key1=P1^4;         //设置
  14. sbit Key2=P1^5;         //加
  15. sbit Key3=P1^6;         //减
  16. sbit Key4=P1^7;         //确定         
  17. sbit shang=P3^7;//上限
  18. sbit xia=P3^6;//下限

  19. sbit DQ=P2^2;                             //定义DS18B20总线I/O
  20. signed char w,bj,bjx,bjd;                                     //温度值全局变量
  21. uchar c;                                //温度值全局变量
  22. bit bdata flag=0,flag_BJ,flag_off=1,que;
  23. //时间计算
  24. #define Imax 14000    //此处为晶振为11.0592时的取值,
  25. #define Imin 8000    //如用其它频率的晶振时,
  26. #define Inum1 145    //要改变相应的取值。
  27. #define Inum2 700
  28. #define Inum3 3000
  29. //解码变量
  30. unsigned char Im[4]={0x00,0x00,0x00,0x00};

  31. //全局变量
  32. uchar f;
  33. unsigned char m,Tc;
  34. unsigned char IrOK;

  35. //设置变量

  36. uchar xx=29;
  37. //下限
  38. uchar sx=35;
  39. //上限
  40. int ds=0;
  41. uchar Mode=0;

  42. void delay(uint z)
  43. {
  44.         uint i,j;
  45.         for(i=0;i<z;i++)
  46.         for(j=0;j<121;j++);
  47. }
  48. /**************************************************************************************************
  49. **************************温度工作程序*************************************************************
  50. **************************************************************************************************/
  51. /*****延时子程序*****/
  52. void Delay_DS18B20(int num)
  53. {
  54.   while(num--) ;
  55. }
  56. /*****初始化DS18B20*****/
  57. void Init_DS18B20(void)
  58. {
  59.   unsigned char x=0;
  60.   DQ = 1;         //DQ复位
  61.   Delay_DS18B20(8);    //稍做延时
  62.   DQ = 0;         //单片机将DQ拉低
  63.   Delay_DS18B20(8);   //精确延时,大于480us
  64.   DQ = 1;         //拉高总线
  65.   Delay_DS18B20(14);
  66.   x = DQ;           //稍做延时后,如果x=0则初始化成功,x=1则初始化失败
  67.   Delay_DS18B20(20);
  68. }
  69. /*****读一个字节*****/
  70. unsigned char ReadOneChar(void)
  71. {
  72.   unsigned char i=0;
  73.   unsigned char dat = 0;
  74.   for (i=8;i>0;i--)
  75.   {
  76.     DQ = 0;     // 给脉冲信号
  77.     dat>>=1;
  78.     DQ = 1;     // 给脉冲信号
  79.     if(DQ)
  80.     dat|=0x80;
  81.     Delay_DS18B20(4);
  82.   }
  83.   return(dat);
  84. }
  85. /*****写一个字节*****/
  86. void WriteOneChar(unsigned char dat)
  87. {
  88.   unsigned char i=0;
  89.   for (i=8; i>0; i--)
  90.   {
  91.     DQ = 1;
  92.     DQ = dat&0x10;
  93.     Delay_DS18B20(5);
  94.     DQ = 0;
  95.     dat>>=1;
  96.   }
  97. }
  98. /*****读取温度*****/
  99. unsigned int ReadTemperature(void)
  100. {
  101.   unsigned char a=0;
  102.   unsigned char b=0;
  103.   unsigned int t=0;
  104.   float tt=0;
  105.   Init_DS18B20();
  106.   WriteOneChar(0xC1);  //跳过读序号列号的操作
  107.   WriteOneChar(0x44);  //启动温度转换
  108.   Init_DS18B20();
  109.   WriteOneChar(0xC1);  //跳过读序号列号的操作
  110.   WriteOneChar(0xBE);  //读取温度寄存器
  111.   a=ReadOneChar();     //读低8位
  112.   b=ReadOneChar();    //读高8位
  113.   t=b;
  114.   t<<=8;
  115.   t=t|a;
  116.   tt=t*0.00625;
  117.   t= tt*10+0.5;     //放大10倍输出并四舍五入
  118.   return(t);
  119. }


  120. /*****读取温度*****/
  121. void check_wendu(void)
  122. {
  123.         c=ReadTemperature()-5;                          //获取温度值并减去DS18B20的温漂误差
  124.         w=c/10;                                                      //计算得到整数位
  125.         if(w<0){w=0;}                                   //设置温度显示上限
  126.         if(w>99){w=99;}                                   //设置温度显示上限   
  127. }
  128. /**************************************************************************************************
  129. ***************************************************************************************************
  130. **************************************************************************************************/


  131. /**************************************************************************************************
  132. ************************************按键工作程序***************************************************
  133. **************************************************************************************************/
  134. void Key()
  135. {
  136.         //模式选择
  137.         if(Key1==0)
  138.         {
  139.                 while(Key1==0);
  140.                 Feng=0;
  141.                 Mode++;
  142.                 Display_wd();
  143.                 if(Mode==4)
  144.                 {
  145.                         Mode=1;
  146.                         Feng=1;
  147.                 }
  148.                    write_com(0x38);//屏幕初始化
  149.                    write_com(0x0d);//打开显示 无光标 光标闪烁
  150.                    write_com(0x06);//当读或写一个字符是指针后一一位
  151.                 switch(Mode)
  152.                 {
  153.                         case 1:
  154.                         {
  155.                                 write_com(0x80+15);//位置
  156.                                 Feng=1;
  157.                                 break;
  158.                         }
  159.                         case 2:
  160.                         {
  161.                                 write_com(0x80+0x40+5);//位置
  162.                                 Feng=1;
  163.                                 break;
  164.                         }
  165.                         case 3:
  166.                         {
  167.                                 write_com(0x80+0x40+14);//位置
  168.                                 Feng=1;
  169.                                 break;
  170.                         }
  171.                 }
  172.         }
  173.         if(Key2==0&&Mode!=0)
  174.         {
  175.                 while(Key2==0);
  176.                 Feng=0;
  177.                 switch(Mode)
  178.                 {
  179.                         case 1:
  180.                         {
  181.                                 if(ds<999)
  182.                                 {
  183.                                         ds++;
  184.                                         write_com(0x80+13);
  185.                                         write_data('0'+ds/100);
  186.                                         write_data('0'+ds/10%10);
  187.                                         write_data('0'+ds%10);
  188.                                         write_com(0x80+15);//位置
  189.                                 }
  190.                                 Feng=1;
  191.                                 break;
  192.                         }
  193.                         case 2:
  194.                         {
  195.                                 if(sx<99-1)
  196.                                 {
  197.                                         sx++;
  198.                                         write_com(0x80+0x40+4);
  199.                                         write_data('0'+sx/10%10);
  200.                                         write_data('0'+sx%10);
  201.                                         write_com(0x80+0x40+5);//位置
  202.                                 }
  203.                                 Feng=1;
  204.                                 break;                                
  205.                         }
  206.                         case 3:
  207.                         {
  208.                                 if(xx<sx-1)
  209.                                 {
  210.                                         xx++;
  211.                                         write_com(0x80+0x40+13);
  212.                                         write_data('0'+xx/10%10);
  213.                                         write_data('0'+xx%10);
  214.                                         write_com(0x80+0x40+14);//位置
  215.                                 }
  216.                                 Feng=1;
  217.                                 break;                                
  218.                         }               
  219.                 }
  220.         }
  221.         if(Key3==0&&Mode!=0)
  222.         {
  223.                 while(Key3==0);
  224.                 Feng=0;
  225.                 switch(Mode)
  226.                 {
  227.                         case 1:
  228.                         {
  229.                                 if(ds>0)
  230.                                 {
  231.                                         ds--;
  232.                                         write_com(0x80+13);
  233.                                         write_data('0'+ds/100);
  234.                                         write_data('0'+ds/10%10);
  235.                                         write_data('0'+ds%10);
  236.                                         write_com(0x80+15);//位置
  237.                                 }
  238.                                 Feng=1;
  239.                                 break;
  240.                         }
  241.                         case 2:
  242.                         {
  243.                                 if(sx>xx+1)
  244.                                 {
  245.                                         sx--;
  246.                                         write_com(0x80+0x40+4);
  247.                                         write_data('0'+sx/10%10);
  248.                                         write_data('0'+sx%10);
  249.                                         write_com(0x80+0x40+5);//位置
  250.                                 }
  251.                                 Feng=1;
  252.                                 break;                                
  253.                         }
  254.                         case 3:
  255.                         {
  256.                                 if(xx>0)
  257.                                 {
  258.                                         xx--;
  259.                                         write_com(0x80+0x40+13);
  260.                                         write_data('0'+xx/10%10);
  261.                                         write_data('0'+xx%10);
  262.                                         write_com(0x80+0x40+14);//位置
  263.                                 }
  264.                                 Feng=1;
  265.                                 break;                                
  266.                         }               
  267.                 }
  268.         }
  269.         if(Key4==0)
  270.         {
  271.                 while(Key4==0);
  272.                 Feng=0;
  273.                 Mode=0;
  274.         //        write_com(0x38);//屏幕初始化
  275.         //        write_com(0x0c);//打开显示 无光标 无光标闪烁
  276.                 Init1602();
  277.                 if(ds>0)
  278.                 {
  279.                         flag=1;
  280.                         jdq=1;
  281.                         TR1=1;
  282.                 }
  283.                 Feng=1;
  284.         }
  285.                 if(IrOK==1)
  286.                 {
  287.                         if(Im[2]==0x0d)        //遥控设置键
  288.                         {
  289.                                 Feng=0;
  290.                                 Mode++;
  291.                                 Display_wd();
  292.                                 if(Mode==4)
  293.                                 {
  294.                                         Mode=1;
  295.                                         Feng=1;
  296.                                 }
  297.                                    write_com(0x38);//屏幕初始化
  298.                                    write_com(0x0d);//打开显示 无光标 光标闪烁
  299.                                    write_com(0x06);//当读或写一个字符是指针后一一位
  300.                                 switch(Mode)
  301.                                 {
  302.                                         case 1:
  303.                                         {
  304.                                                 write_com(0x80+15);//位置
  305.                                                 Feng=1;
  306.                                                 break;
  307.                                         }
  308.                                         case 2:
  309.                                         {
  310.                                                 write_com(0x80+0x40+5);//位置
  311.                                                 Feng=1;
  312.                                                 break;
  313.                                         }
  314.                                         case 3:
  315.                                         {
  316.                                                 write_com(0x80+0x40+14);//位置
  317.                                                 Feng=1;
  318.                                                 break;
  319.                                         }
  320.                                 }                                 
  321.                         }
  322.                         //+键
  323.                         else if(Im[2]==0x40)
  324.                         {
  325.                                 if(Mode!=0)
  326.                                 {
  327.                                         Feng=0;
  328.                                         switch(Mode)
  329.                                         {
  330.                                                 case 1:
  331.                                                 {
  332.                                                         if(ds<999)
  333.                                                         {
  334.                                                                 ds++;
  335.                                                                 write_com(0x80+13);
  336.                                                                 write_data('0'+ds/100);
  337.                                                                 write_data('0'+ds/10%10);
  338.                                                                 write_data('0'+ds%10);
  339.                                                                 write_com(0x80+15);//位置
  340.                                                         }
  341.                                                         Feng=1;
  342.                                                         break;
  343.                                                 }
  344.                                                 case 2:
  345.                                                 {
  346.                                                         if(sx<99-1)
  347.                                                         {
  348.                                                                 sx++;
  349.                                                                 write_com(0x80+0x40+4);
  350.                                                                 write_data('0'+sx/10%10);
  351.                                                                 write_data('0'+sx%10);
  352.                                                                 write_com(0x80+0x40+5);//位置
  353.                                                         }
  354.                                                         Feng=1;
  355.                                                         break;                                
  356.                                                 }
  357.                                                 case 3:
  358.                                                 {
  359.                                                         if(xx<sx-1)
  360.                                                         {
  361.                                                                 xx++;
  362.                                                                 write_com(0x80+0x40+13);
  363.                                                                 write_data('0'+xx/10%10);
  364.                                                                 write_data('0'+xx%10);
  365.                                                                 write_com(0x80+0x40+14);//位置
  366.                                                         }
  367.                                                         Feng=1;
  368.                                                         break;                                
  369.                                                 }               
  370.                                         }
  371.                                 }
  372.                         }
  373.                         //-键
  374.                         else if(Im[2]==0x19)
  375.                         {
  376.                                 if(Mode!=0)
  377.                                 {
  378.                                         Feng=0;
  379.                                         switch(Mode)
  380.                                         {
  381.                                                 case 1:
  382.                                                 {
  383.                                                         if(ds>0)
  384.                                                         {
  385.                                                                 ds--;
  386.                                                                 write_com(0x80+13);
  387.                                                                 write_data('0'+ds/100);
  388.                                                                 write_data('0'+ds/10%10);
  389.                                                                 write_data('0'+ds%10);
  390.                                                                 write_com(0x80+15);//位置
  391.                                                         }
  392.                                                         Feng=1;
  393.                                                         break;
  394.                                                 }
  395.                                                 case 2:
  396.                                                 {
  397.                                                         if(sx>xx+1)
  398.                                                         {
  399.                                                                 sx--;
  400.                                                                 write_com(0x80+0x40+4);
  401.                                                                 write_data('0'+sx/10%10);
  402.                                                                 write_data('0'+sx%10);
  403.                                                                 write_com(0x80+0x40+5);//位置
  404.                                                         }
  405.                                                         Feng=1;
  406.                                                         break;                                
  407.                                                 }
  408.                                                 case 3:
  409.                                                 {
  410.                                                         if(xx>0)
  411.                                                         {
  412.                                                                 xx--;
  413.                                                                 write_com(0x80+0x40+13);
  414.                                                                 write_data('0'+xx/10%10);
  415.                                                                 write_data('0'+xx%10);
  416.                                                                 write_com(0x80+0x40+14);//位置
  417.                                                         }
  418.                                                         Feng=1;
  419.                                                         break;                                
  420.                                                 }               
  421.                                         }
  422.                                 }
  423.                         }
  424.                         //确定键
  425.                         else if(Im[2]==0x15)
  426.                         {
  427.                                 Feng=0;
  428.                                 Mode=0;
  429.                                 Init1602();
  430.                                 if(ds>0)
  431.                                 {
  432.                                         flag=1;
  433.                                         jdq=1;
  434.                                         TR1=1;
  435.                                 }
  436.                                 Feng=1;
  437.                         }
  438.                         IrOK=0;         
  439.                 }
  440. }
  441. /**************************************************************************************************
  442. ***************************************************************************************************
  443. **************************************************************************************************/



  444. /**************************************************************************************************
  445. ************************************报警部分程序***************************************************
  446. **************************************************************************************************/
  447. void Alam()
  448. {
  449.         if(flag_BJ==1&&flag_off==1)
  450.         {
  451.                 Feng=0;
  452.                 delay(1000);
  453.                 Feng=1;
  454.                 flag_off=0;
  455. //                flag_BJ=0;
  456.         }
  457. }
  458. /**************************************************************************************************
  459. ***************************************************************************************************
  460. **************************************************************************************************/

  461. /**************************************************************************************************
  462. *********************************************主程序************************************************
  463. **************************************************************************************************/
  464. void main()
  465. {
  466.         Init1602();
  467.         EA=1;//打开中断总开关
  468.         IT1=1;//下降沿有效
  469.         EX1=1;//外部中断1开
  470.         ET1=1;//打开允许开关
  471.         TMOD=0x01;//设置工作方式
  472.         TL1=0x3c;
  473.         TH1=0xb0;//赋初值
  474.         TH0=0;//T0赋初值
  475.         TL0=0;
  476.         TR0=0;//t0开始计时
  477.         check_wendu();
  478.         delay(1000);
  479.         bjd=99;
  480.         bjx=0;                                 //这两个变量的作用就是,防止温度大范围跳动造成加热设备误动作
  481.         while(1)
  482.         {        
  483.                 check_wendu();
  484.                 if(Mode==0)
  485.                 {        
  486.                         Display_1602(c,ds,sx,xx);
  487.                         if((xia==1)&&(shang==1)) //低于下限
  488.                         {
  489.                                  que=1;
  490.                                 shui=0;
  491.                                 jdq=1;
  492.                         }
  493.                         else
  494.                         {
  495.                                 que=0;
  496.                         }
  497.                         if((shang==0)&&(xia==0)) //高于上限
  498.                         {
  499.                                 shui=1;
  500.                                 if(flag_BJ==0)
  501.                                 flag_BJ=1;
  502.                         }
  503.                         if((shang==0)&&(xia==1)) //错误
  504.                         {
  505.                                 shui=1;
  506.                                 jdq=1;
  507.                                 Feng=0;
  508.                                 que=1;
  509.                         }
  510.                         if(flag==0)
  511.                         {
  512.                                 if((w<bjd)&&(w>bjx))
  513.                                 {
  514.                                         if(w>=sx)
  515.                                         {
  516.                                                 jdq=1;
  517.                                                 if(flag_BJ==0)
  518.                                                 flag_BJ=1;
  519.                                         }
  520.                                         else if((w<xx)&&(que==0))         
  521.                                         {
  522.                                                 jdq=0;
  523.                                                 if(flag_BJ==0)
  524.                                                 flag_BJ=1;
  525.                                         }
  526.                                         else
  527.                                         {
  528.                                                 flag_BJ=0;
  529.                                                 flag_off=1;
  530.                                         }
  531.                                         bjd=w+5;
  532.                                         bjx=w-5;
  533.                                 }
  534.                         }
  535.                 }
  536.                 Key();
  537.                 Alam();
  538.         }
  539. }
  540. /**************************************************************************************************
  541. ***************************************************************************************************
  542. **************************************************************************************************/


  543. /**************************************************************************************************
  544. ****************************************定时器工作程序*********************************************
  545. **************************************************************************************************/
  546. void time1() interrupt 3//定时器函数
  547. {
  548.         uint s;
  549.         TH1=0x3c;
  550.         TL1=0xb0;//重新赋初值
  551.         s++;
  552.         if(s==1200)        //s=20为1s钟  1200为1分钟
  553.         {
  554.                 s=0;
  555.                 ds--;
  556.                 if(ds==0)
  557.                 {
  558.                         flag=0;
  559.                         if(w>=sx)
  560.                         {
  561.                                 jdq=1;
  562.                                 if(flag_BJ==0)
  563.                                 flag_BJ=1;
  564.                         }
  565.                         else if((w<xx)&&(que==0))
  566. ……………………

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

本人初学,仅供参考,存在错误和不足之处,请大家回帖多多指教,切勿照搬,文件下载:
新建文件夹.rar (2.31 MB, 下载次数: 363)


评分

参与人数 1黑币 +8 收起 理由
ZONE-9 + 8 共享资料的黑币奖励!

查看全部评分

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

使用道具 举报

沙发
ID:461751 发表于 2019-1-5 13:22 | 只看该作者
nice啊
回复

使用道具 举报

板凳
ID:461751 发表于 2019-1-12 16:47 | 只看该作者
楼主,用你那程序仿真后,lcd第二行不显示,温度传感器也无法调解温度,能解释一下原因不,非常感谢
回复

使用道具 举报

地板
ID:375715 发表于 2019-1-14 00:35 来自手机 | 只看该作者
很好(▽)
回复

使用道具 举报

5#
ID:539513 发表于 2019-5-16 08:21 | 只看该作者
太对了
回复

使用道具 举报

6#
ID:632048 发表于 2019-10-29 14:47 | 只看该作者
很想学习单片机
回复

使用道具 举报

7#
ID:676474 发表于 2019-12-29 10:28 | 只看该作者
有很大的用处
回复

使用道具 举报

8#
ID:686251 发表于 2020-2-28 12:09 | 只看该作者
本帖最后由 Hopeful 于 2020-3-4 19:11 编辑

很好,就是那个c 运行到第二行没有,也没检测到啥毛病
回复

使用道具 举报

9#
ID:447960 发表于 2020-3-22 13:21 | 只看该作者
#include <display.h>这个为什么说找不到头文件啊
回复

使用道具 举报

10#
ID:720111 发表于 2020-4-1 16:01 | 只看该作者
这个没有自动加水功能吧
回复

使用道具 举报

11#
ID:1029488 发表于 2022-5-25 09:48 | 只看该作者
pandahu 发表于 2019-1-12 16:47
楼主,用你那程序仿真后,lcd第二行不显示,温度传感器也无法调解温度,能解释一下原因不,非常感谢

他的代码调用的芯片和你的不一样
回复

使用道具 举报

12#
ID:1011458 发表于 2022-5-25 15:05 | 只看该作者
实际应用效果如何
回复

使用道具 举报

13#
ID:1031404 发表于 2022-5-31 23:10 来自手机 | 只看该作者
为什么这个原理图温度低于最低温度的时候不会报警啊
回复

使用道具 举报

14#
ID:1047200 发表于 2022-12-16 09:06 来自手机 | 只看该作者
楼主,这个红外遥控无法使用是什么原因呀
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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