|
|
STM32熱水器
單片機(jī)源程序如下:
- //各種頭文件,不可缺少
- #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; //默認(rèn)上限值60度
- void kaiji()
- {
- BEEP=1;
- OLED_ZWString(35,15,"歡迎使用",16);
- OLED_ZWString(30,40,"數(shù)字熱水器",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;
-
- //顯示時(shí)間年月日
- sprintf(str,"%4d-%02d-%02d",calendar.w_year,calendar.w_month,calendar.w_date);
- OLED_ShowString(25,0 ,str,16 );
- //顯示時(shí)間時(shí)分秒
- 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); //顯示整數(shù)部分
- OLED_ShowChar(48+8+24,45,'.',16,1);
- OLED_ShowNum(48+8+32,45,temperature%10,1,16); //顯示小數(shù)部分
- OLED_ZWString(48+8+42,45,"℃",16);
- OLED_Refresh_Gram(); //更新顯示到OLED
- }
- void set_to_oled() //設(shè)置菜單
- {
- OLED_Clear();
-
- OLED_ZWString(48,0,"設(shè)置",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,"時(shí)間",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() //設(shè)置時(shí)間菜單
- {
- 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;//時(shí)鐘結(jié)構(gòu)體
- //取得當(dāng)前時(shí)間
- 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;
- //顯示時(shí)間設(shè)置頁面
- OLED_Clear();
- OLED_ZWString(32,0,"設(shè)置",16);
- OLED_ZWString(64,00,"時(shí)間",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) //選擇年月日時(shí)分秒
- {
- 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) //選擇年月日時(shí)分秒
- {
- 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: //光標(biāo)根據(jù)Num增加,由年月日時(shí)分秒變化
- Num++;
- if(Num==6) //設(shè)置完秒后保存時(shí)間
- {
- 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: //退出時(shí)間設(shè)置,并且不保存
- return ;
-
- }
- delay_ms(100);
- temp++;
- if(temp%3==0&&temp%6!=0) //光標(biāo)閃爍
- {
- 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) //顯示設(shè)定的時(shí)間
- {
- 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() //設(shè)置水溫菜單
- {
- short water_temp=water_flag,TH,TL;
- u8 temp,key,Num=0;
- //顯示水溫設(shè)置界面
- OLED_Clear();
- OLED_ZWString(32,2,"設(shè)置",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); //顯示正數(shù)部分
- OLED_ZWString(66+16+26,25,"℃",16);
- OLED_ZWString(48,48,"返回",16);
-
-
- //取得水溫上限值: 90度————》900
- TH=water_temp/100; //得到十位 9
- TL=water_temp%100/10; //得到個(gè)位 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: //設(shè)置完十位保存設(shè)定值
- Num++;
- if(Num==2)
- {
- water_flag =water_temp;
- AT24CXX_WriteOneByte(10,water_temp/10);
- return ;
- }
- break;
- case KEY3_PRES: //退出菜單,不保存設(shè)定值
- return ;
- }
- water_temp=TH*100+TL*10;//得到設(shè)定的新上限值
- delay_ms(100);
- temp++;
- if(temp%3==0&&temp%6!=0) //光標(biāo)閃爍
- {
- 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); //顯示正數(shù)部分
- OLED_Refresh_Gram(); //更新顯示到OLED
- }
-
-
- }
- }
- void init_module() //數(shù)據(jù)初始化
- {
- u8 temp= AT24CXX_ReadOneByte(10); //讀出存儲(chǔ)設(shè)定值
- if(AT24CXX_Check()==0 && temp <=99 && temp >=0) //設(shè)定值 0--99度
- {
- water_flag=temp*10; //設(shè)定值 0--99度 ---》0——990方便比較
- OLED_Clear();
- OLED_ZWString(20,15,"數(shù)據(jù)讀取成功",16);
- OLED_ZWString(36,34,"上限",16);
- OLED_ShowNum(68,34,water_flag/10,2,16); //顯示正數(shù)部分
- OLED_ZWString(68+16,34,"℃",16);
- OLED_Refresh_Gram(); //更新顯示到OLED
- }
- else //讀取失敗,數(shù)據(jù)異常,都默認(rèn)為60度
- {
- OLED_ZWString(24,15,"存儲(chǔ)器異常",16);
- OLED_ZWString(16,34,"默認(rèn)上限",16);
- OLED_ShowNum(80,34,60,2,16); //顯示正數(shù)部分
- 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() //根據(jù)水溫控制繼電器、蜂鳴器
- {
- short temperature;
-
- temperature=DS18B20_Get_Temp();
- if(water_flag<=temperature) //水溫高于設(shè)定 蜂鳴器報(bào)警 繼電器停止加熱
- {
- BEEP=!BEEP;
- SW=0;
- }
- else //水溫低于設(shè)定 蜂鳴器關(guān)閉 繼電器啟動(dòng)加熱
- {
- BEEP=0;
- SW=1;
- }
-
- }
- /************************************************
- 主程序部分
- ************************************************/
-
- int main(void)
- {
- u8 t=0;
- u8 sec_temp;
- u8 key=0,Mune;
- delay_init(); //延時(shí)函數(shù)初始化
- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //設(shè)置NVIC中斷分組2:2位搶占優(yōu)先級(jí),2位響應(yīng)優(yōu)先級(jí)
- LED_Init(); //LED端口初始化
- OLED_Init(); //初始化OLED
- BEEP_Init(); //蜂鳴器初始化
- KEY_Init(); //按鍵初始化
- RTC_Init(); //RTC時(shí)鐘初始化
- DS18B20_Init(); //DS18B20初始化
- AT24CXX_Init(); //AT24C02初始化
- kaiji(); //開機(jī)界面
-
- init_module(); //讀出存儲(chǔ)的溫度值,并且判斷是否正常
-
- sec_temp=calendar.sec; //將秒數(shù)賦值給sec_temp變量
- while(1)
- {
-
- key=KEY_Scan(0); //得到鍵值
-
- if(key==KEY0_PRES) //按下第0按鍵————》進(jìn)入菜單選擇
- {
- set_to_oled(); //顯示設(shè)置菜單
- delay_ms(100);
- Mune=1;
- while(Mune) //Mune=1時(shí)死循環(huán),0退出
- {
- key=KEY_Scan(0); //得到鍵值,沒有按下則返回0
- switch(key)
- {
- case KEY0_PRES: break; //按下第0按鍵————》退出菜單
- case KEY3_PRES: break; //按下第3按鍵————》退出菜單
- case KEY1_PRES:
- set_water(); //按下第1按鍵————》設(shè)置水溫上限
- break;
- case KEY2_PRES:
- set_time(); //按下第1按鍵————》設(shè)置時(shí)間
- break;
- }
- if(key!=0) //任意一個(gè)按鍵按鍵
- {
- Mune=0; //Mune=1時(shí)死循環(huán),0退出死循環(huán)
- OLED_Clear(); //清屏
- }
- delay_ms(100);
- }
- }
-
- if(sec_temp!=calendar.sec)//每一秒刷新一次頁面
- {
- sec_temp=calendar.sec;
- dsy_to_oled(); //顯示時(shí)間、水溫
- warm(); //根據(jù)水溫控制繼電器、蜂鳴器
- }
-
- delay_ms(100);
- t++;
- if(t%20==0) //每隔2S led燈狀態(tài)變化一次,用來表示系統(tǒng)一直運(yùn)行
- {
- LED0=!LED0;
- }
- }
-
- }
復(fù)制代碼
所有資料51hei提供下載:
STM32熱水器.7z
(226.09 KB, 下載次數(shù): 43)
2019-5-1 02:25 上傳
點(diǎn)擊文件名下載附件
STM32熱水器
|
|