STM32热水器
单片机源程序如下:
- //各种头文件,不可缺少
- #include "led.h"
- #include "delay.h"
- #include "key.h"
- #include "sys.h"
- #include "oled.h"
- #include "rtc.h"
- #include "beep.h"
- #include "stdio.h"
- #include "usart.h"
- #include "DS18B20.h"
- #include "24cxx.h"
- u8 str[50];
- short water_flag=600; //默认上限值60度
- void kaiji()
- {
- BEEP=1;
- OLED_ZWString(35,15,"欢迎使用",16);
- OLED_ZWString(30,40,"数字热水器",16);
- OLED_Refresh_Gram(); //更新显示到OLED
- delay_ms(800);
- BEEP=0;
- delay_ms(800);
-
- BEEP=1;
- OLED_Clear();
- OLED_ZWString(40,15,"杨凯锋",16);
- // OLED_ZWString(30,40,"电信",16);
- // OLED_ShowNum(80,40,131,3,16);
- OLED_Refresh_Gram(); //更新显示到OLED
- delay_ms(800);
- BEEP=0;
- delay_ms(800);
- OLED_Clear();
- }
- void dsy_to_oled() //主界面显示
- {
- short temperature;
-
- //显示时间年月日
- sprintf(str,"%4d-%02d-%02d",calendar.w_year,calendar.w_month,calendar.w_date);
- OLED_ShowString(25,0 ,str,16 );
- //显示时间时分秒
- sprintf(str,"%02d:%02d:%02d",calendar.hour,calendar.min,calendar.sec);
- OLED_ShowString(10,23,str,16 );
- //显示周
- OLED_ZWNUM(90,23,calendar.week,16);
- //读出温度
- temperature=DS18B20_Get_Temp();
- OLED_ZWString(16,45,"水温",16);
- OLED_ShowChar(48,45,':',16,1);
- //显示温度值
- OLED_ShowNum(48+8+8,45,temperature/10,2,16); //显示整数部分
- OLED_ShowChar(48+8+24,45,'.',16,1);
- OLED_ShowNum(48+8+32,45,temperature%10,1,16); //显示小数部分
- OLED_ZWString(48+8+42,45,"℃",16);
- OLED_Refresh_Gram(); //更新显示到OLED
- }
- void set_to_oled() //设置菜单
- {
- OLED_Clear();
-
- OLED_ZWString(48,0,"设置",16);
- OLED_ShowNum(2,16,1,1,16); //显示1
- OLED_ZWString(20,16,"水温",16);
- OLED_ShowNum(2,32,2,1,16); //显示2
- OLED_ZWString(20,32,"时间",16);
- OLED_ShowNum(2,48,3,1,16); //显示3
- OLED_ZWString(20,48,"返回",16);
- OLED_Refresh_Gram(); //更新显示到OLED
- BEEP=0;
- SW=0;
- }
- void set_time() //设置时间菜单
- {
- const u8 mon_table[12]={31,28,31,30,31,30,31,31,30,31,30,31};
- u8 temp,key,Num=0;
- _calendar_obj set_time;//时钟结构体
- //取得当前时间
- set_time.w_year=calendar.w_year;
- set_time.w_month=calendar.w_month;
- set_time.w_date=calendar.w_date;
- set_time.hour=calendar.hour;
- set_time.min=calendar.min;
- set_time.sec=calendar.sec;
- //显示时间设置页面
- OLED_Clear();
- OLED_ZWString(32,0,"设置",16);
- OLED_ZWString(64,00,"时间",16);
- sprintf(str,"%4d-%02d-%02d",calendar.w_year,calendar.w_month,calendar.w_date);
- OLED_ShowString(25,16 ,str,16 );
- sprintf(str,"%02d:%02d:%02d",calendar.hour,calendar.min,calendar.sec);
- OLED_ShowString(25,32,str,16 );
- OLED_ZWString(20,48,"返回",16);
- OLED_Refresh_Gram(); //更新显示到OLED
- while(1)
- {
- key=KEY_Scan(0); //得到键值
- switch(key)
- {
- case KEY1_PRES: //加1
- switch(Num) //选择年月日时分秒
- {
- case 0:
- set_time.w_year++;
- if(set_time.w_year>=2099)
- set_time.w_year = 1970;
- break;
- case 1:
- set_time.w_month++;
- if(set_time.w_month>=13)
- set_time.w_month = 1;
- break;
- case 2:
- set_time.w_date++;
- if(set_time.w_date>mon_table[set_time.w_month-1])
- set_time.w_date = 1;
- break;
- case 3:
- set_time.hour++;
- if(set_time.hour>=24)
- set_time.hour = 0;
- break;
- case 4:
- set_time.min++;
- if(set_time.min>=60)
- set_time.min = 0;
- break;
- case 5:
- set_time.sec++;
- if(set_time.sec>=60)
- set_time.sec = 0;
- break;
- }
- break;
- case KEY2_PRES: //减1
- switch(Num) //选择年月日时分秒
- {
- case 0:
- set_time.w_year--;
- if(set_time.w_year<=1970)
- set_time.w_year = 2099;
- break;
- case 1:
- set_time.w_month--;
- if(set_time.w_month==0)
- set_time.w_month = 12;
- break;
- case 2:
- set_time.w_date--;
- if(set_time.w_date == 0)
- set_time.w_date = mon_table[set_time.w_month-1];
- break;
- case 3:
-
- if(set_time.hour == 0)
- set_time.hour = 24;
-
- set_time.hour--;
- break;
- case 4:
-
- if(set_time.min==0)
- set_time.min = 60;
- set_time.min--;
- break;
- case 5:
-
- if(set_time.sec==0)
- set_time.sec = 60;
- set_time.sec--;
- break;
- }
- break;
- case KEY0_PRES: //光标根据Num增加,由年月日时分秒变化
- Num++;
- if(Num==6) //设置完秒后保存时间
- {
- RTC_Set(set_time.w_year,set_time.w_month,set_time.w_date,set_time.hour,set_time.min,set_time.sec);
- return ;
- }break;
- case KEY3_PRES: //退出时间设置,并且不保存
- return ;
-
- }
- delay_ms(100);
- temp++;
- if(temp%3==0&&temp%6!=0) //光标闪烁
- {
- switch(Num)
- {
- case 0:
- OLED_ShowString(25,16,"____",16);
- break;
- case 1:
- OLED_ShowString(65,16,"__",16);
- break;
- case 2:
- OLED_ShowString(89,16,"__",16);
- break;
- case 3:
- OLED_ShowString(25,32,"__",16);
- break;
- case 4:
- OLED_ShowString(49,32,"__",16);
- break;
- case 5:
- OLED_ShowString(73,32,"__",16);
- break;
-
- }
- OLED_Refresh_Gram(); //更新显示到OLED
- }
- else if(temp%6==0) //显示设定的时间
- {
- sprintf(str,"%4d-%02d-%02d",set_time.w_year,set_time.w_month,set_time.w_date);
- OLED_ShowString(25,16 ,str,16 );
- sprintf(str,"%02d:%02d:%02d",set_time.hour,set_time.min,set_time.sec);
- OLED_ShowString(25,32,str,16 );
- OLED_Refresh_Gram(); //更新显示到OLED
- }
- }
- }
- void set_water() //设置水温菜单
- {
- short water_temp=water_flag,TH,TL;
- u8 temp,key,Num=0;
- //显示水温设置界面
- OLED_Clear();
- OLED_ZWString(32,2,"设置",16);
- OLED_ZWString(64,2,"水温",16);
-
- OLED_ZWString(2,25,"水温",16);
- OLED_ZWString(34,25,"上限",16);
- OLED_ShowChar(66,25,':',16,1);
- OLED_ShowNum(66+16,25,water_temp/10,2,16); //显示正数部分
- OLED_ZWString(66+16+26,25,"℃",16);
- OLED_ZWString(48,48,"返回",16);
-
-
- //取得水温上限值: 90度————》900
- TH=water_temp/100; //得到十位 9
- TL=water_temp%100/10; //得到个位 0
- while(1)
- {
- key=KEY_Scan(0); //得到键值
- switch(key)
- {
- case KEY1_PRES:
- switch(Num)
- {
- case 0:
- TL++;
- if(TL>=10)
- {
- TH++;
- if(TH>=10)TH=0;
- TL=0;
- }
- break;
- case 1:
- TH++;
- if(TH>=10)TH=0;
- break;
- }
- break;
- case KEY2_PRES:
- switch(Num)
- {
- case 0:
-
- if(TL==0)
- {
-
- if(TH==0)TH=10;
- TH--;
- TL=10;
- }
- TL--;
- break;
- case 1:
-
- if(TH==0)TH=10;
- TH--;
- break;
- }
- break;
- case KEY0_PRES: //设置完十位保存设定值
- Num++;
- if(Num==2)
- {
- water_flag =water_temp;
- AT24CXX_WriteOneByte(10,water_temp/10);
- return ;
- }
- break;
- case KEY3_PRES: //退出菜单,不保存设定值
- return ;
- }
- water_temp=TH*100+TL*10;//得到设定的新上限值
- delay_ms(100);
- temp++;
- if(temp%3==0&&temp%6!=0) //光标闪烁
- {
- switch(Num)
- {
- case 1:
- OLED_ShowString(66+16,25,"_",16);
- break;
- case 0:
- OLED_ShowString(66+16+8,25,"_",16);
- break;
- }
- OLED_Refresh_Gram(); //更新显示到OLED
- }
- else if(temp%6==0) //显示上限值
- {
- OLED_ShowNum(66+16,25,water_temp/10,2,16); //显示正数部分
- OLED_Refresh_Gram(); //更新显示到OLED
- }
-
-
- }
- }
- void init_module() //数据初始化
- {
- u8 temp= AT24CXX_ReadOneByte(10); //读出存储设定值
- if(AT24CXX_Check()==0 && temp <=99 && temp >=0) //设定值 0--99度
- {
- water_flag=temp*10; //设定值 0--99度 ---》0——990方便比较
- OLED_Clear();
- OLED_ZWString(20,15,"数据读取成功",16);
- OLED_ZWString(36,34,"上限",16);
- OLED_ShowNum(68,34,water_flag/10,2,16); //显示正数部分
- OLED_ZWString(68+16,34,"℃",16);
- OLED_Refresh_Gram(); //更新显示到OLED
- }
- else //读取失败,数据异常,都默认为60度
- {
- OLED_ZWString(24,15,"存储器异常",16);
- OLED_ZWString(16,34,"默认上限",16);
- OLED_ShowNum(80,34,60,2,16); //显示正数部分
- OLED_ZWString(80+16,34,"℃",16);
- AT24CXX_WriteOneByte(10,60); //写入60
- OLED_Refresh_Gram(); //更新显示到OLED
-
- }
- delay_ms(1000);
- delay_ms(1000);
- OLED_Clear();
- }
- void warm() //根据水温控制继电器、蜂鸣器
- {
- short temperature;
-
- temperature=DS18B20_Get_Temp();
- if(water_flag<=temperature) //水温高于设定 蜂鸣器报警 继电器停止加热
- {
- BEEP=!BEEP;
- SW=0;
- }
- else //水温低于设定 蜂鸣器关闭 继电器启动加热
- {
- BEEP=0;
- SW=1;
- }
-
- }
- /************************************************
- 主程序部分
- ************************************************/
-
- int main(void)
- {
- u8 t=0;
- u8 sec_temp;
- u8 key=0,Mune;
- delay_init(); //延时函数初始化
- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
- LED_Init(); //LED端口初始化
- OLED_Init(); //初始化OLED
- BEEP_Init(); //蜂鸣器初始化
- KEY_Init(); //按键初始化
- RTC_Init(); //RTC时钟初始化
- DS18B20_Init(); //DS18B20初始化
- AT24CXX_Init(); //AT24C02初始化
- kaiji(); //开机界面
-
- init_module(); //读出存储的温度值,并且判断是否正常
-
- sec_temp=calendar.sec; //将秒数赋值给sec_temp变量
- while(1)
- {
-
- key=KEY_Scan(0); //得到键值
-
- if(key==KEY0_PRES) //按下第0按键————》进入菜单选择
- {
- set_to_oled(); //显示设置菜单
- delay_ms(100);
- Mune=1;
- while(Mune) //Mune=1时死循环,0退出
- {
- key=KEY_Scan(0); //得到键值,没有按下则返回0
- switch(key)
- {
- case KEY0_PRES: break; //按下第0按键————》退出菜单
- case KEY3_PRES: break; //按下第3按键————》退出菜单
- case KEY1_PRES:
- set_water(); //按下第1按键————》设置水温上限
- break;
- case KEY2_PRES:
- set_time(); //按下第1按键————》设置时间
- break;
- }
- if(key!=0) //任意一个按键按键
- {
- Mune=0; //Mune=1时死循环,0退出死循环
- OLED_Clear(); //清屏
- }
- delay_ms(100);
- }
- }
-
- if(sec_temp!=calendar.sec)//每一秒刷新一次页面
- {
- sec_temp=calendar.sec;
- dsy_to_oled(); //显示时间、水温
- warm(); //根据水温控制继电器、蜂鸣器
- }
-
- delay_ms(100);
- t++;
- if(t%20==0) //每隔2S led灯状态变化一次,用来表示系统一直运行
- {
- LED0=!LED0;
- }
- }
-
- }
复制代码
所有资料51hei提供下载:
STM32热水器.7z
(226.09 KB, 下载次数: 43)
|