#include "led.h" #include "delay.h" #include "sys.h" #include "usart.h" #include "wifi.h" #include "lcd1602.h" #include "adc.h" #include "timer.h" #include "string.h" #include "ds18b20.h" #include "Lcd_Driver.h" #include #include #include #include "DS1302.h" #include "oled.h" #include "key.h" // 0 - 加热模式 (手动启动/设定时间自动启动) // 1 - 杀菌模式 // 2 - 保温模式 // 用户数据的结构体 struct UserInfo{ float water_temp; int now_tager_temp; int water_target_temp; int model; // 模块 0-加热模式 1-杀菌模式 2-保温模式 struct timing SetTimer; // 设定时间 u8 TimerFlag; u8 HotFlag; u8 Heating_state; u8 Water_pump; float water_level; u16 setLevel; }; struct RegulatoryTasks { int hour; int min; int sec; u8 flag; float temp; }; struct UserInfo userInfo; struct timing nowTime; u8 Settime[6]={0x22,0x04,0x27,0x19,0x17,0x20}; // 设置时间 22年 03月 27日 22:34:00 int setModel = 0; int change = 0; // 函数声明 int getValue(void); int getFirstIndexes(const char str); int getLastIndexes(const char str); u8 getTimerResult(void); struct timing getTimer(void); void Sys_Init(void); void DisplayTask(void); void TaskProcessing(void); void DataProcessing(void); /** * @description: main函数 * @param {*} * @return {*} */ int main(void) { Sys_Init(); delay_ms(1000); BEEP = 1; while(1) { TaskProcessing(); DataProcessing(); DS1302_Readtime(); DisplayTask(); delay_ms(200); } } /** * @description: 系统初始化 * @param {*} * @return {*} */ void Sys_Init(void) { delay_init(); NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); uart_init(115200); Model_Init(); LED_Init(); DS18B20_Init(); Adc_Init(); // 水位模块 OLED_Init(); Key4x4_GPIO_Config(); DS1302_init(Settime); //DS1302_SetTime(Settime); OLED_Clear(); } /** * @description: 显示 * @param {*} * @return {*} */ void DisplayTask(void) { char str[30]; if(setModel == 0){ sprintf(str,"%2d-%2d %2d:%2d:%2d ", nowTime.mon, nowTime.day, nowTime.hour, nowTime.min, nowTime.sec); OLED_ShowString(0, 0, str, 16); sprintf(str,"%0.2fC %dC %0.2fcm %d", userInfo.water_temp, userInfo.now_tager_temp,userInfo.water_level, userInfo.setLevel); OLED_ShowString(0, 2, str, 16); }else{ sprintf(str,"%2dC Level:%d %d", userInfo.water_target_temp,userInfo.setLevel, change); OLED_ShowString(0, 0, str, 16); sprintf(str,"%2d-%2d-%2d %2d:%2d:%2d T:%d,H:%d", userInfo.SetTimer.year,userInfo.SetTimer.mon, userInfo.SetTimer.day, userInfo.SetTimer.hour, userInfo.SetTimer.min, userInfo.SetTimer.sec, userInfo.TimerFlag, userInfo.HotFlag); OLED_ShowString(0, 2, str, 16); } }; /** * @description: 报警 * @param {*} * @return {*} */ void Warning(){ BEEP = 0; delay_ms(100); BEEP = 1; } /** * @description: 加热水 目标温度 * @param {*} * @return {*} */ int HeatWaterTask(int target_temp) { static struct RegulatoryTasks task; int result; userInfo.now_tager_temp = target_temp; // 定时加热开启后的监管任务,如5分钟内温度变化在2摄氏度内,则中断加热 if(task.flag && userInfo.Heating_state){ if(task.hour == nowTime.hour && task.min == nowTime.min && task.sec == nowTime.sec){ // 温度无变化,关闭加热 if(fabs(task.temp - userInfo.water_temp) <= 2){ HOT = 0; task.flag = 0; printf("No change in temperature, Turn off heating\r\n"); } } } // 时间生效时为自动模式,否则为手动模式 if(userInfo.TimerFlag){ result = getTimerResult(); if(result && task.flag == 0){ printf("Time to heat up!\r\n"); Warning(); HOT = 1; task.flag = 1; task.hour = nowTime.hour; task.min = nowTime.min; task.sec = nowTime.sec; task.temp = userInfo.water_temp; // 过五分钟 task.min += 1; if(task.min > 59){ task.min = task.min - 60; task.hour += 1; if(task.hour > 23) task.hour = task.hour - 24; } }else if(result == 0 && task.flag == 0){ // 时间未到默认关闭 HOT = 0; } else if(!userInfo.Heating_state) task.flag = 0; }else{ task.flag = 0; // 时间不生效时默认由HotFlag控制是否加热 HOT = userInfo.HotFlag; } // 判断水位过低、或温度达到 if(userInfo.water_level < 1 || userInfo.water_temp == target_temp) { HOT = 0; task.flag = 0; if(userInfo.water_level < 1) return 1; if(userInfo.water_temp >= target_temp) return 2; } return 0; } /** * @description: 更改水位 0-低水位 1-中水位 2-高水位 * @param {*} * @return {*} */ void ChageWaterLevelTask() { double WaterH = 2, WaterL = 1.0; if(userInfo.setLevel == 1) WaterH = 3, WaterL = 2; else if(userInfo.setLevel == 2) WaterH = 4, WaterL = 3; // 加水 if(userInfo.water_level < WaterL){ // 启动水泵 MOTOR = 1; }else if(userInfo.water_level >= WaterL && userInfo.water_level < WaterH){ // 关闭水泵 MOTOR = 0; }else if(userInfo.water_level > WaterH){ // 黄灯闪烁 LED_YELLOW = 1; delay_ms(100); LED_YELLOW = 0; MOTOR = 0; } if(userInfo.water_level < 1 && userInfo.Heating_state){ LED_RED = 1; BEEP = 0; delay_ms(100); LED_RED = 0; BEEP = 1; } } /** * @description: 加热模式 (控制水位、自动模式(定时加热水、不可手动开关热水功能)、手动模块(手动开关热水功能)) * @param {*} * @return {*} */ void HeatingModeTask() { // 温度达到进入保温模式 if(HeatWaterTask(userInfo.water_target_temp) == 2){ printf("The temperature reached:%d", userInfo.water_target_temp); BEEP = 0; delay_ms(100); BEEP = 1; userInfo.model = 2; } } /** * @description: 杀菌模式 (加热到80度, 在降温到设定的温度) * @param {*} * @return {*} */ void SterilizationModeTask() { static u8 flag = 0; if(flag == 0){ if(HeatWaterTask(30) == 2){ printf("The temperature reached:%d", 80); BEEP = 0; delay_ms(100); BEEP = 1; userInfo.now_tager_temp = userInfo.water_target_temp; userInfo.model = 2; flag = 1; } }else{ // 关闭加热 userInfo.TimerFlag = 0; userInfo.HotFlag = 0; // 温度达到进入保温模式 if(HeatWaterTask(userInfo.water_target_temp) == 2) { printf("The temperature reached:%d", userInfo.water_target_temp); BEEP = 0; delay_ms(100); BEEP = 1; userInfo.model = 2; } } } /** * @description: 保温模式 * @param {*} * @return {*} */ void HeatPreservationModetask() { if(userInfo.water_temp <= (userInfo.water_target_temp - 1)) { userInfo.TimerFlag = 0; userInfo.HotFlag = 1; // 切换为加热模式 userInfo.model = 0; } } /** * @description: 改变值 * @param {int} Value * @return {*} */ void ChangeValue(int Value){ if(setModel != 1) return; switch(change){ case 0: if(userInfo.water_target_temp < 10){ userInfo.water_target_temp = userInfo.water_target_temp * 10 + Value; } break; case 1: userInfo.setLevel = Value; if(userInfo.setLevel >= 3) userInfo.setLevel = 2; break; case 2: if(userInfo.SetTimer.year < 10){ userInfo.SetTimer.year = userInfo.SetTimer.year * 10 + Value; } break; case 3: if(userInfo.SetTimer.mon < 10){ userInfo.SetTimer.mon = userInfo.SetTimer.mon * 10 + Value; if(userInfo.SetTimer.mon > 12) userInfo.SetTimer.mon = 12; } break; case 4: if(userInfo.SetTimer.day < 10){ userInfo.SetTimer.day = userInfo.SetTimer.day* 10 + Value; if(userInfo.SetTimer.day > 31) userInfo.SetTimer.day = 31; } break; case 5: if(userInfo.SetTimer.hour < 10){ userInfo.SetTimer.hour = userInfo.SetTimer.hour * 10 + Value; if(userInfo.SetTimer.hour > 23) userInfo.SetTimer.hour = 23; } break; case 6: if(userInfo.SetTimer.min < 10){ userInfo.SetTimer.min = userInfo.SetTimer.min * 10 + Value; if(userInfo.SetTimer.min > 59) userInfo.SetTimer.min = 59; } break; case 7: if(userInfo.SetTimer.sec < 10){ userInfo.SetTimer.sec = userInfo.SetTimer.sec * 10 + Value; if(userInfo.SetTimer.sec > 59) userInfo.SetTimer.sec = 59; } break; } } /** * @description: 删除键 * * @param {*} * @return {*} */ void DeleteValue() { if(setModel != 1) return; switch(change){ case 0: userInfo.water_target_temp /= 10; break; case 1: userInfo.setLevel /= 10; break; case 2: userInfo.SetTimer.year /= 10; break; case 3: userInfo.SetTimer.mon /= 10; break; case 4: userInfo.SetTimer.day /= 10; break; case 5: userInfo.SetTimer.hour /= 10; break; case 6: userInfo.SetTimer.min /= 10; break; case 7: userInfo.SetTimer.sec /= 10; break; } } /** * @description: 按键处理 * @param {*} * @return {*} */ void keyHandling(){ int key = 16; key = Key_Scan(); switch (key) { case 12: if(setModel == 0) setModel = 1; else setModel = 0; OLED_Clear(); break; case 13: change++; if(change >= 8) change = 0; break; case 14: if(userInfo.HotFlag == 0) userInfo.HotFlag = 1; else userInfo.HotFlag = 0; break; case 15: if(userInfo.TimerFlag == 0) userInfo.TimerFlag = 1; else userInfo.TimerFlag = 0; break; case 11: DeleteValue(); break; default: if(!setModel || key == 16) break; if(key < 10) ChangeValue(key); break; } } /** * @description: 任务处理 * @param {*} * @return {*} */ void TaskProcessing() { float temp; u16 num; keyHandling(); if(setModel == 0){ // 获取数据 // 获取水温 userInfo.water_temp = DS18B20_Get_Temp() / 10; num = Get_Adc_Average(ADC_Channel_1,10); temp = (float)num * (10 / 4096 / 3.3); // 以最高水位10cm来算 userInfo.water_level = temp; // 获取加热棒状态 userInfo.Heating_state = HOT; // 处于加热模式 定时生效 if(userInfo.model == 0) HeatingModeTask(); else if(userInfo.model == 1) SterilizationModeTask(); else if(userInfo.model == 2) HeatPreservationModetask(); ChageWaterLevelTask(); } } /** * @description: 判断时间是否到达 * @param {*} * @return {*} */ u8 getTimerResult(void) { u8 result = 1; // 不考虑年 //if(userInfo.SetTimer.year != nowTime.year) result = 0; if(userInfo.SetTimer.mon != nowTime.mon) result = 0; else if(userInfo.SetTimer.day != nowTime.day) result = 0; else if(userInfo.SetTimer.hour != nowTime.hour) result = 0; else if(userInfo.SetTimer.min != nowTime.min) result = 0; else if(userInfo.SetTimer.sec != nowTime.sec) result = 0; return result; } /** * @description: 解析数据 * @param {*} * @return {*} */ int getValue(void) { int target1 = 0, target2 = 0,i = 0; int result = 0; target1 = (char *)strstr((const char *)USART_RX_BUF, "(") - (char *)USART_RX_BUF; target2 = (char *)strstr((const char *)USART_RX_BUF, ")") - (char *)USART_RX_BUF; result = 0; for(i = target1 + 1; i < target2; i++){ result = result * 10 + (*(USART_RX_BUF + i) - 0x30); } return result; } /** * @description: 获取字符出现的第一个索引 * @param {char} str * @return {*} */ int getFirstIndexes(const char str){ int i = 0; int length = USART_RX_STA & 0x3fff; for(i = 0; i < length; i++){ if(str == USART_RX_BUF[i]) return i; } return 0; } /** * @description: 获取字符出现的最后一个索引 * @param {char} str * @return {*} */ int getLastIndexes(const char str){ int result = 0, i = 0; int length = USART_RX_STA & 0x3fff; for(i = 0; i < length; i++){ if(str == USART_RX_BUF[i]) result = i; } return result; } /** * @description: 解析Timer * @param {*} * @return {*} */ struct timing getTimer() { struct timing timer; int target1 = 0, target2 = 0,i = 0 , result = 0; target1 = (char *)strstr((const char *)USART_RX_BUF, "(") - (char *)USART_RX_BUF; target2 = getFirstIndexes('-'); for(i = target1 + 1; i < target2; i++){ result = result * 10 + (*(USART_RX_BUF + i) - 0x30); } timer.year = result; result = 0; target1 = getFirstIndexes('-'); target2 = getLastIndexes('-'); for(i = target1 + 1; i < target2; i++){ result = result * 10 + (*(USART_RX_BUF + i) - 0x30); } timer.mon = result; result = 0; target1 = getLastIndexes('-'); target2 = getFirstIndexes(' '); for(i = target1 + 1; i < target2; i++){ result = result * 10 + (*(USART_RX_BUF + i) - 0x30); } timer.day = result; result = 0; target1 = getFirstIndexes(' '); target2 = getFirstIndexes(':'); for(i = target1 + 1; i < target2; i++){ result = result * 10 + (*(USART_RX_BUF + i) - 0x30); } timer.hour = result; result = 0; target1 = getFirstIndexes(':'); target2 = getLastIndexes(':'); for(i = target1 + 1; i < target2; i++){ result = result * 10 + (*(USART_RX_BUF + i) - 0x30); } timer.min = result; result = 0; target1 = getLastIndexes(':'); target2 = getLastIndexes(')'); for(i = target1 + 1; i < target2; i++){ result = result * 10 + (*(USART_RX_BUF + i) - 0x30); } timer.sec = result; return timer; } /** * @description: 接收数据 * @param {*} * @return {*} */ void DataProcessing(void) { // 接受到数据 if(USART_RX_STA & 0x8000){ // 模式切换 if(strstr((const char*)USART_RX_BUF, "model") != NULL){ userInfo.model++; if(userInfo.model >= 2) userInfo.model = 0; if(userInfo.model == 0) printf("The heating mode\r\n"); else if(userInfo.model == 1) printf("Sterilization mode\r\n"); } if(strstr((const char*)USART_RX_BUF, "getModel") != NULL){ if(userInfo.model == 0) printf("The heating mode\r\n"); else if(userInfo.model == 1) printf("Sterilization mode\r\n"); else printf("Heat preservation mode\r\n"); } if(strstr((const char*)USART_RX_BUF, "setTargetTemp") != NULL){ userInfo.water_target_temp = getValue(); printf("setTargetTemp OK!\r\n"); } if(strstr((const char*)USART_RX_BUF, "setTimer") != NULL){ userInfo.SetTimer = getTimer(); printf("setTimer OK!\r\n"); } if(strstr((const char*)USART_RX_BUF, "setLevel") != NULL){ userInfo.setLevel = getValue(); if(userInfo.setLevel >= 3) userInfo.setLevel = 2; printf("setLevel OK!\r\n"); } if(strstr((const char*)USART_RX_BUF, "TimerFlag") != NULL){ if(userInfo.TimerFlag == 0) userInfo.TimerFlag = 1; else userInfo.TimerFlag = 0; if(userInfo.TimerFlag == 0) printf("Close Timer!\r\n"); else printf("Open Timer!\r\n"); } if(strstr((const char*)USART_RX_BUF, "HotFlag") != NULL){ if(userInfo.HotFlag == 0) userInfo.HotFlag = 1; else userInfo.HotFlag = 0; if(userInfo.HotFlag == 0) printf("Close Hot!\r\n"); else printf("Open Hot!\r\n"); } if(strstr((const char*)USART_RX_BUF, "getInfo") != NULL){ printf("Water_temp:%0.1f℃, target:%d℃, setTemp:%d ℃, water_level:%0.2fcm, TimerFlag:%d , HotFlag:%d\r\n", userInfo.water_temp, userInfo.now_tager_temp,userInfo.water_target_temp, userInfo.water_level, userInfo.TimerFlag, userInfo.HotFlag); } if(strstr((const char*)USART_RX_BUF, "getTime") != NULL){ printf("Time: 20%d-%d-%d %d:%d:%d\r\n", nowTime.year, nowTime.mon, nowTime.day, nowTime.hour, nowTime.min, nowTime.sec); } if(strstr((const char*)USART_RX_BUF, "getTimer") != NULL){ printf("Timer: %d-%d-%d %d:%d:%d\r\n", userInfo.SetTimer.year, userInfo.SetTimer.mon, userInfo.SetTimer.day, userInfo.SetTimer.hour, userInfo.SetTimer.min, userInfo.SetTimer.sec); } memset(USART_RX_BUF, 0, sizeof(USART_RX_BUF)); USART_RX_STA = 0x00; } }