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)
2019-5-1 02:25 上傳
點擊文件名下載附件
STM32熱水器
|