找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1971|回复: 2
收起左侧

STM32热水器控制程序

[复制链接]
ID:525413 发表于 2019-4-30 23:58 | 显示全部楼层 |阅读模式
STM32热水器

单片机源程序如下:
  1. //各种头文件,不可缺少
  2. #include "led.h"
  3. #include "delay.h"
  4. #include "key.h"
  5. #include "sys.h"
  6. #include "oled.h"
  7. #include "rtc.h"                     
  8. #include "beep.h"
  9. #include "stdio.h"
  10. #include "usart.h"          
  11. #include "DS18B20.h"
  12. #include "24cxx.h"

  13. u8 str[50];
  14. short water_flag=600;  //默认上限值60度

  15. void kaiji()
  16. {
  17.         BEEP=1;
  18.         OLED_ZWString(35,15,"欢迎使用",16);
  19.         OLED_ZWString(30,40,"数字热水器",16);
  20.         OLED_Refresh_Gram();                //更新显示到OLED
  21.         delay_ms(800);
  22.         BEEP=0;
  23.         delay_ms(800);
  24.        
  25.         BEEP=1;
  26.         OLED_Clear();
  27.         OLED_ZWString(40,15,"杨凯锋",16);
  28. //        OLED_ZWString(30,40,"电信",16);
  29. //        OLED_ShowNum(80,40,131,3,16);
  30.         OLED_Refresh_Gram();                //更新显示到OLED
  31.         delay_ms(800);
  32.         BEEP=0;
  33.         delay_ms(800);

  34.         OLED_Clear();
  35. }


  36. void dsy_to_oled()  //主界面显示
  37. {
  38.         short temperature;
  39.        
  40.         //显示时间年月日
  41.         sprintf(str,"%4d-%02d-%02d",calendar.w_year,calendar.w_month,calendar.w_date);
  42.         OLED_ShowString(25,0 ,str,16 );
  43.         //显示时间时分秒
  44.         sprintf(str,"%02d:%02d:%02d",calendar.hour,calendar.min,calendar.sec);
  45.         OLED_ShowString(10,23,str,16 );
  46.         //显示周
  47.   OLED_ZWNUM(90,23,calendar.week,16);

  48.         //读出温度
  49.         temperature=DS18B20_Get_Temp();       
  50.         OLED_ZWString(16,45,"水温",16);
  51.         OLED_ShowChar(48,45,':',16,1);                       

  52.         //显示温度值
  53.         OLED_ShowNum(48+8+8,45,temperature/10,2,16);        //显示整数部分       
  54.         OLED_ShowChar(48+8+24,45,'.',16,1);                                       
  55.         OLED_ShowNum(48+8+32,45,temperature%10,1,16);        //显示小数部分                
  56.         OLED_ZWString(48+8+42,45,"℃",16);

  57.         OLED_Refresh_Gram();                //更新显示到OLED

  58. }


  59. void set_to_oled()  //设置菜单
  60. {

  61.         OLED_Clear();
  62.        
  63.         OLED_ZWString(48,0,"设置",16);
  64.         OLED_ShowNum(2,16,1,1,16);        //显示1               
  65.         OLED_ZWString(20,16,"水温",16);
  66.         OLED_ShowNum(2,32,2,1,16);        //显示2        
  67.         OLED_ZWString(20,32,"时间",16);
  68.         OLED_ShowNum(2,48,3,1,16);        //显示3               
  69.         OLED_ZWString(20,48,"返回",16);
  70.         OLED_Refresh_Gram();                //更新显示到OLED
  71.         BEEP=0;
  72.         SW=0;
  73. }


  74. void set_time()  //设置时间菜单
  75. {
  76.         const u8 mon_table[12]={31,28,31,30,31,30,31,31,30,31,30,31};
  77.         u8 temp,key,Num=0;
  78.         _calendar_obj set_time;//时钟结构体

  79.         //取得当前时间
  80.         set_time.w_year=calendar.w_year;
  81.         set_time.w_month=calendar.w_month;
  82.         set_time.w_date=calendar.w_date;
  83.         set_time.hour=calendar.hour;
  84.         set_time.min=calendar.min;
  85.         set_time.sec=calendar.sec;

  86.         //显示时间设置页面
  87.         OLED_Clear();
  88.         OLED_ZWString(32,0,"设置",16);
  89.         OLED_ZWString(64,00,"时间",16);
  90.         sprintf(str,"%4d-%02d-%02d",calendar.w_year,calendar.w_month,calendar.w_date);
  91.         OLED_ShowString(25,16 ,str,16 );
  92.         sprintf(str,"%02d:%02d:%02d",calendar.hour,calendar.min,calendar.sec);
  93.         OLED_ShowString(25,32,str,16 );
  94.         OLED_ZWString(20,48,"返回",16);
  95.         OLED_Refresh_Gram();                //更新显示到OLED

  96.         while(1)
  97.         {
  98.                 key=KEY_Scan(0);        //得到键值
  99.                 switch(key)
  100.                 {                                 
  101.                         case KEY1_PRES:         //加1
  102.                                                 switch(Num)  //选择年月日时分秒
  103.                                                 {
  104.                                                         case 0:       
  105.                                                                         set_time.w_year++;
  106.                                                                         if(set_time.w_year>=2099)
  107.                                                                                 set_time.w_year = 1970;
  108.                                                                         break;
  109.                                                         case 1:                 
  110.                                                                         set_time.w_month++;
  111.                                                                         if(set_time.w_month>=13)
  112.                                                                                 set_time.w_month = 1;
  113.                                                                         break;
  114.                                                         case 2:
  115.                                                                         set_time.w_date++;
  116.                                                                         if(set_time.w_date>mon_table[set_time.w_month-1])
  117.                                                                                         set_time.w_date = 1;
  118.                                                                         break;
  119.                                                         case 3:       
  120.                                                                         set_time.hour++;
  121.                                                                         if(set_time.hour>=24)
  122.                                                                                 set_time.hour = 0;
  123.                                                                         break;
  124.                                                         case 4:       
  125.                                                                         set_time.min++;
  126.                                                                         if(set_time.min>=60)
  127.                                                                                 set_time.min = 0;
  128.                                                                         break;
  129.                                                         case 5:       
  130.                                                                         set_time.sec++;
  131.                                                                         if(set_time.sec>=60)
  132.                                                                                 set_time.sec = 0;
  133.                                                                         break;

  134.                                                 }
  135.                                 break;
  136.                         case KEY2_PRES:        //减1
  137.                                         switch(Num) //选择年月日时分秒
  138.                                                 {
  139.                                                         case 0:       
  140.                                                                         set_time.w_year--;
  141.                                                                         if(set_time.w_year<=1970)
  142.                                                                                 set_time.w_year = 2099;
  143.                                                                         break;
  144.                                                         case 1:                 
  145.                                                                         set_time.w_month--;
  146.                                                                         if(set_time.w_month==0)
  147.                                                                                 set_time.w_month = 12;
  148.                                                                         break;
  149.                                                         case 2:
  150.                                                                         set_time.w_date--;
  151.                                                                         if(set_time.w_date == 0)
  152.                                                                                         set_time.w_date = mon_table[set_time.w_month-1];
  153.                                                                         break;
  154.                                                         case 3:       
  155.                                                                        
  156.                                                                         if(set_time.hour == 0)
  157.                                                                                 set_time.hour = 24;
  158.                                                                        
  159.                                                                         set_time.hour--;
  160.                                                                         break;
  161.                                                         case 4:       
  162.                                                                        
  163.                                                                         if(set_time.min==0)
  164.                                                                                 set_time.min = 60;
  165.                                                                         set_time.min--;
  166.                                                                         break;
  167.                                                         case 5:       
  168.                                                                
  169.                                                                         if(set_time.sec==0)
  170.                                                                                 set_time.sec = 60;
  171.                                                                         set_time.sec--;
  172.                                                                         break;

  173.                                                 }
  174.                                 break;
  175.                         case KEY0_PRES: //光标根据Num增加,由年月日时分秒变化
  176.                                 Num++;
  177.                                 if(Num==6) //设置完秒后保存时间
  178.                                 {         
  179.                                         RTC_Set(set_time.w_year,set_time.w_month,set_time.w_date,set_time.hour,set_time.min,set_time.sec);
  180.                                         return ;
  181.                                 }break;
  182.                         case KEY3_PRES:        //退出时间设置,并且不保存
  183.                                 return ;
  184.                        
  185.                 }
  186.                 delay_ms(100);
  187.                 temp++;
  188.                 if(temp%3==0&&temp%6!=0) //光标闪烁
  189.                 {
  190.                         switch(Num)
  191.                         {
  192.                                 case 0:       
  193.                                                         OLED_ShowString(25,16,"____",16);
  194.                                                         break;
  195.                                 case 1:                 
  196.                                                         OLED_ShowString(65,16,"__",16);
  197.                                                         break;
  198.                                 case 2:
  199.                                                         OLED_ShowString(89,16,"__",16);
  200.                                                         break;
  201.                                 case 3:       
  202.                                                         OLED_ShowString(25,32,"__",16);
  203.                                                         break;
  204.                                 case 4:       
  205.                                                         OLED_ShowString(49,32,"__",16);
  206.                                                         break;
  207.                                 case 5:       
  208.                                                         OLED_ShowString(73,32,"__",16);
  209.                                                         break;
  210.        
  211.                         }
  212.                         OLED_Refresh_Gram();                //更新显示到OLED
  213.                 }
  214.                 else if(temp%6==0)  //显示设定的时间
  215.                 {
  216.                         sprintf(str,"%4d-%02d-%02d",set_time.w_year,set_time.w_month,set_time.w_date);
  217.                         OLED_ShowString(25,16 ,str,16 );
  218.                         sprintf(str,"%02d:%02d:%02d",set_time.hour,set_time.min,set_time.sec);
  219.                         OLED_ShowString(25,32,str,16 );
  220.                         OLED_Refresh_Gram();                //更新显示到OLED
  221.                 }

  222.         }
  223. }


  224. void set_water()        //设置水温菜单
  225. {
  226.         short water_temp=water_flag,TH,TL;
  227.         u8 temp,key,Num=0;
  228.         //显示水温设置界面
  229.         OLED_Clear();
  230.         OLED_ZWString(32,2,"设置",16);
  231.         OLED_ZWString(64,2,"水温",16);
  232.   
  233.         OLED_ZWString(2,25,"水温",16);
  234.         OLED_ZWString(34,25,"上限",16);  
  235.         OLED_ShowChar(66,25,':',16,1);                       
  236.         OLED_ShowNum(66+16,25,water_temp/10,2,16);        //显示正数部分       
  237.         OLED_ZWString(66+16+26,25,"℃",16);
  238.         OLED_ZWString(48,48,"返回",16);
  239.        
  240.        
  241.         //取得水温上限值:   90度————》900
  242.         TH=water_temp/100;  //得到十位 9
  243.         TL=water_temp%100/10; //得到个位 0

  244.         while(1)
  245.         {
  246.                 key=KEY_Scan(0);        //得到键值
  247.                 switch(key)
  248.                 {                               
  249.                         case KEY1_PRES:
  250.                                                 switch(Num)
  251.                                                 {
  252.                                                         case 0:                 
  253.                                                                         TL++;
  254.                                                                         if(TL>=10)
  255.                                                                         {       
  256.                                                                                 TH++;
  257.                                                                                 if(TH>=10)TH=0;                                                                       
  258.                                                                                 TL=0;
  259.                                                                         }
  260.                                                                         break;
  261.                                                         case 1:
  262.                                                                         TH++;
  263.                                                                         if(TH>=10)TH=0;                       
  264.                                                                         break;
  265.                                                 }
  266.                                                 break;
  267.                         case KEY2_PRES:
  268.                                                 switch(Num)
  269.                                                 {
  270.                                                         case 0:                 
  271.                                                                        
  272.                                                                         if(TL==0)
  273.                                                                         {       
  274.                                                                                
  275.                                                                                 if(TH==0)TH=10;       
  276.                                                                                 TH--;                                                                               
  277.                                                                                 TL=10;
  278.                                                                         }
  279.                                                                         TL--;
  280.                                                                         break;
  281.                                                         case 1:
  282.                                                                        
  283.                                                                         if(TH==0)TH=10;               
  284.                                                                         TH--;                                                       
  285.                                                                         break;
  286.                                                 }               
  287.                                                 break;
  288.                         case KEY0_PRES: //设置完十位保存设定值
  289.                                                 Num++;
  290.                                                 if(Num==2)
  291.                                                 {       
  292.                                                         water_flag =water_temp;
  293.                                                         AT24CXX_WriteOneByte(10,water_temp/10);

  294.                                                         return ;
  295.                                                 }
  296.                                                 break;
  297.                         case KEY3_PRES:         //退出菜单,不保存设定值
  298.                                                 return ;
  299.                 }
  300.                 water_temp=TH*100+TL*10;//得到设定的新上限值
  301.                 delay_ms(100);
  302.                 temp++;
  303.                 if(temp%3==0&&temp%6!=0)  //光标闪烁
  304.                 {
  305.                         switch(Num)
  306.                         {
  307.                                 case 1:       
  308.                                                         OLED_ShowString(66+16,25,"_",16);
  309.                                                         break;
  310.                                 case 0:                 
  311.                                                         OLED_ShowString(66+16+8,25,"_",16);
  312.                                                         break;
  313.                         }
  314.                         OLED_Refresh_Gram();                //更新显示到OLED
  315.                 }
  316.                 else if(temp%6==0)  //显示上限值
  317.                 {
  318.                                 OLED_ShowNum(66+16,25,water_temp/10,2,16);        //显示正数部分       
  319.                                 OLED_Refresh_Gram();                //更新显示到OLED
  320.                 }

  321.        
  322.        
  323.         }
  324. }


  325. void init_module() //数据初始化
  326. {
  327.         u8 temp= AT24CXX_ReadOneByte(10);  //读出存储设定值
  328.         if(AT24CXX_Check()==0 && temp <=99 && temp >=0)  //设定值 0--99度
  329.         {
  330.                         water_flag=temp*10;  //设定值 0--99度  ---》0——990方便比较
  331.                         OLED_Clear();
  332.                         OLED_ZWString(20,15,"数据读取成功",16);       
  333.                         OLED_ZWString(36,34,"上限",16);
  334.                         OLED_ShowNum(68,34,water_flag/10,2,16);        //显示正数部分       
  335.                         OLED_ZWString(68+16,34,"℃",16);
  336.                         OLED_Refresh_Gram();                //更新显示到OLED
  337.         }
  338.         else   //读取失败,数据异常,都默认为60度
  339.         {
  340.                 OLED_ZWString(24,15,"存储器异常",16);       
  341.                 OLED_ZWString(16,34,"默认上限",16);
  342.                 OLED_ShowNum(80,34,60,2,16);        //显示正数部分       
  343.                 OLED_ZWString(80+16,34,"℃",16);
  344.                 AT24CXX_WriteOneByte(10,60); //写入60
  345.                 OLED_Refresh_Gram();                //更新显示到OLED
  346.        
  347.         }
  348.         delay_ms(1000);
  349.         delay_ms(1000);
  350.         OLED_Clear();


  351. }

  352. void warm()   //根据水温控制继电器、蜂鸣器
  353. {
  354.         short temperature;
  355.        
  356.         temperature=DS18B20_Get_Temp();       
  357.         if(water_flag<=temperature)   //水温高于设定 蜂鸣器报警 继电器停止加热
  358.         {
  359.                 BEEP=!BEEP;
  360.                 SW=0;
  361.         }
  362.         else  //水温低于设定 蜂鸣器关闭 继电器启动加热
  363.         {       
  364.                 BEEP=0;
  365.                 SW=1;
  366.         }
  367.                
  368. }



  369. /************************************************
  370. 主程序部分
  371. ************************************************/
  372.        
  373.         int main(void)
  374. {       
  375.         u8 t=0;
  376.         u8 sec_temp;
  377.         u8 key=0,Mune;       

  378.         delay_init();                     //延时函数初始化          
  379.         NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);         //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
  380.         LED_Init();                             //LED端口初始化
  381.         OLED_Init();                        //初始化OLED      
  382.         BEEP_Init();                        //蜂鸣器初始化
  383.         KEY_Init();                         //按键初始化
  384.         RTC_Init();                                //RTC时钟初始化
  385.         DS18B20_Init();   //DS18B20初始化
  386.         AT24CXX_Init();   //AT24C02初始化
  387.         kaiji();                                        //开机界面
  388.                                         

  389.         init_module();                 //读出存储的温度值,并且判断是否正常
  390.        
  391.         sec_temp=calendar.sec; //将秒数赋值给sec_temp变量

  392.          while(1)
  393.         {               
  394.                
  395.                 key=KEY_Scan(0);        //得到键值
  396.                
  397.                 if(key==KEY0_PRES)  //按下第0按键————》进入菜单选择
  398.                 {
  399.                         set_to_oled();                //显示设置菜单
  400.                         delay_ms(100);
  401.                         Mune=1;                       
  402.                         while(Mune)                //Mune=1时死循环,0退出
  403.                         {
  404.                                 key=KEY_Scan(0);        //得到键值,没有按下则返回0
  405.                                 switch(key)
  406.                                 {                                 
  407.                                         case KEY0_PRES: break;  //按下第0按键————》退出菜单
  408.                                         case KEY3_PRES:        break;  //按下第3按键————》退出菜单
  409.                                         case KEY1_PRES:
  410.                                                         set_water();                                 //按下第1按键————》设置水温上限
  411.                                                         break;
  412.                                         case KEY2_PRES:         
  413.                                                         set_time();                                        //按下第1按键————》设置时间
  414.                                                         break;
  415.                                 }
  416.                                 if(key!=0)  //任意一个按键按键
  417.                                 {       
  418.                                         Mune=0;   //Mune=1时死循环,0退出死循环
  419.                                         OLED_Clear();  //清屏
  420.                                 }
  421.                                 delay_ms(100);
  422.                         }
  423.                 }
  424.                
  425.                 if(sec_temp!=calendar.sec)//每一秒刷新一次页面
  426.                 {               
  427.                         sec_temp=calendar.sec;
  428.                         dsy_to_oled();        //显示时间、水温
  429.                         warm();                                        //根据水温控制继电器、蜂鸣器
  430.                 }       
  431.                
  432.                  delay_ms(100);
  433.                 t++;
  434.                 if(t%20==0)  //每隔2S led灯状态变化一次,用来表示系统一直运行
  435.                 {
  436.                         LED0=!LED0;
  437.                 }

  438.         }          
  439.        
  440. }
复制代码

所有资料51hei提供下载:
STM32热水器.7z (226.09 KB, 下载次数: 43)
回复

使用道具 举报

ID:1 发表于 2019-5-1 02:25 | 显示全部楼层
本帖需要重新编辑补全电路原理图,源码,详细说明与图片即可获得100+黑币(帖子下方有编辑按钮)
回复

使用道具 举报

ID:525460 发表于 2019-5-1 10:06 来自手机 | 显示全部楼层
感谢分享
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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