diff --git a/Src/config.h b/Src/config.h index d709740..e850dd1 100644 --- a/Src/config.h +++ b/Src/config.h @@ -24,4 +24,6 @@ typedef uint8_t u8; sbit SDA = P2 ^ 7; sbit SCL = P2 ^ 6; +#define AUTO_STOP_POWER 1 // 自动停止功率阈值 + #endif \ No newline at end of file diff --git a/Src/main.c b/Src/main.c index 566853e..b475d44 100644 --- a/Src/main.c +++ b/Src/main.c @@ -15,8 +15,33 @@ // #include "dht10.h" #include "oled12864_drv.h" +// 系统状态枚举 +typedef enum +{ + MODE_AUTO_OFF, // 自动断电模式 + MODE_MANUAL, // 手动模式 + MODE_FIXED_TIME // 固定时长模式 +} ChargeMode; + +typedef struct +{ + ChargeMode mode; + uint8_t is_charging; + uint16_t charge_duration; // 单位:sec + uint32_t start_time; + uint32_t stop_time; +} ChargeSys; + +ChargeSys sys_state = { MODE_MANUAL, 0, 10, 0, 0 }; // 系统状态结构体 +ChargeSys last_sys_state + = { MODE_MANUAL, 0, 10, 0, 0 }; // 上一次系统状态结构体 + +// 函数声明 void packDataAndSent (uint16_t vol, uint16_t cur, uint16_t pwr, uint16_t tmp, - uint16_t hum); // 数据打包函数 + uint16_t hum); // 数据打包函数 +void Process_Keys_Event (u8 key_pressed); // 按键处理函数 +void StartCharge (); // 开始充电 +void StopCharge (); // 停止充电 void SystemClock_Init (void) @@ -25,16 +50,20 @@ SystemClock_Init (void) CLK_DIV = 0x00; // 时钟不分频(30MHz直接输出) } +// INA226数据 +u16 ina226_voltage = 0; +u16 ina226_current = 0; +u16 ina226_power = 0; + +/******************************************* + * 主函数 + *******************************************/ void main () { uint32_t last_round_time = 0; uint32_t this_round_time = 0; - u16 ina226_voltage = 0; - u16 ina226_current = 0; - u16 ina226_power = 0; - char *p_json_str = NULL; SystemClock_Init (); // 时钟配置 @@ -67,10 +96,16 @@ main () // OLED_ShowPrintf (96, 4, ".", OLED_FONT_EIGHT, OLED_LEFT_ROLL, OLED_CLS); // OLED_ShowPrintf (96, 5, ".", OLED_FONT_EIGHT, OLED_LEFT_ROLL, OLED_CLS); + OLED_ShowPrintf (16, 6, "MANUAL", OLED_FONT_SIXTEEN, OLED_LEFT_ROLL, + OLED_CLS); // 初始化为手动模式 + P2M1 &= 0xFE; // P20为推挽输出 P2M0 |= 0x01; P20 = 1; // P20为推挽输出 + sys_state.mode = MODE_AUTO_OFF; // 初始化为常闭模式 + StopCharge (); // 停止充电 + while (1) { ina226_voltage = (int16_t)(INA226_ReadBusVoltage () * 100); @@ -118,8 +153,7 @@ main () ); Key_Scan (); - OLED_ShowNum (0, 6, Get_KeyEvents (), 3, OLED_FONT_SIXTEEN, - OLED_LEFT_ROLL, OLED_SHOW); + Process_Keys_Event (Get_KeyEvents ()); } } @@ -148,3 +182,144 @@ Uart1_Isr (void) interrupt 4 RI = 0; // 清除串口1接收中断请求位 } } + +/******************************************* + * 按键处理函数 + * 需在主循环中调用 + *******************************************/ +void +Process_Keys_Event (u8 key_pressed) +{ + static u8 key_pressed_last = 0; + + if (key_pressed) + { + // KEY1处理:启动/停止充电 + if (key_pressed & 0x08) + { + sys_state.is_charging ^= 1; // 充电状态切换 + if (sys_state.mode == MODE_FIXED_TIME && sys_state.is_charging == 1) + // 定实模式下切换进充电状态时 记录相关时间点 + { + sys_state.start_time = GetUpTime (); + sys_state.stop_time + = sys_state.start_time + sys_state.charge_duration; + StartCharge (); + } + else if ((sys_state.mode == MODE_FIXED_TIME) + && (sys_state.is_charging == 0)) + // 定实模式下切换出充电状态时 记录剩余时间 + { + sys_state.charge_duration = GetUpTime () - sys_state.start_time; + StopCharge (); + } + } + + // KEY2处理:模式切换 + if (key_pressed & 0x04) + { + if (++sys_state.mode > MODE_FIXED_TIME) + { + sys_state.mode = MODE_AUTO_OFF; + } + } + + // KEY3/KEY4处理:时间调整(仅在固定模式下有效) + if (sys_state.mode == MODE_FIXED_TIME) + { + if (key_pressed & 0x02) + { // KEY3:增加时间 + if (sys_state.charge_duration < 1440) + { // 24小时上限 + sys_state.charge_duration += 10; + } + } + if (key_pressed & 0x01) + { // KEY4:减少时间 + if (sys_state.charge_duration > 1) + { + sys_state.charge_duration -= 10; + } + } + } + } + + if (last_sys_state.mode != sys_state.mode) // 模式切换 + { + OLED_Row_Clear (6, 2, OLED_CLS); // 清除状态栏显示 + OLED_ShowPrintf (0, 6, "M", OLED_FONT_SIXTEEN, OLED_LEFT_ROLL, + OLED_SHOW); + switch (sys_state.mode) + { + case MODE_AUTO_OFF: + OLED_ShowPrintf (16, 6, "AUTO_OFF", OLED_FONT_SIXTEEN, + OLED_LEFT_ROLL, OLED_CLS); + break; + case MODE_MANUAL: + OLED_ShowPrintf (16, 6, "MANUAL", OLED_FONT_SIXTEEN, OLED_LEFT_ROLL, + OLED_CLS); + break; + case MODE_FIXED_TIME: + OLED_ShowPrintf (16, 6, "TIME Sec", OLED_FONT_SIXTEEN, + OLED_LEFT_ROLL, OLED_CLS); + } + last_sys_state.mode = sys_state.mode; // 更新状态 + } + + if (sys_state.mode == MODE_FIXED_TIME) // 固定时间模式下显示时间 + { + if (sys_state.is_charging == 1) // 充电中 显示时间 + { + if (sys_state.stop_time < GetUpTime ()) // 充电时间已到 停止充电 + { + OLED_ShowNum (56, 6, 0x00, 4, OLED_FONT_SIXTEEN, OLED_LEFT_ROLL, + OLED_CLS); // 显示 0 sec + sys_state.is_charging = 0; // 停止充电 + } + else // 充电中 显示剩余时间 单位:秒 + { + OLED_ShowNum (56, 6, sys_state.stop_time - GetUpTime (), 4, + OLED_FONT_SIXTEEN, OLED_LEFT_ROLL, OLED_CLS); + } + } + else // 未启动充电 加深时间文字 表示正在设置充电时间 + { + OLED_ShowNum (56, 6, sys_state.charge_duration, 4, OLED_FONT_SIXTEEN, + OLED_LEFT_ROLL, OLED_SHOW); + } + } + else if (sys_state.mode == MODE_AUTO_OFF) + { // 自动停止充电模式 + static uint8_t power_under_limite_times = 0; // 充电功率低于阈值次数 + if (ina226_power < AUTO_STOP_POWER) // 充电功率低于阈值 + { + power_under_limite_times++; + } + if (power_under_limite_times >= 100) + { // 充电功率低于阈值100次 + StopCharge (); // 停止充电 + power_under_limite_times = 0; // 重置次数 + } + } + + if (sys_state.is_charging != last_sys_state.is_charging) // 充电状态切换 + { + sys_state.is_charging ? StartCharge () : StopCharge (); // 启动/停止充电 + last_sys_state.is_charging = sys_state.is_charging; // 更新状态 + } +} + +void +StartCharge (void) +{ + OLED_ShowPrintf (64, 4, "Runing ", OLED_FONT_SIXTEEN, OLED_LEFT_ROLL, + OLED_CLS); + P20 = 1; // 启动充电 +} +void +StopCharge (void) +{ + OLED_ShowPrintf (64, 4, "Stopnow", OLED_FONT_SIXTEEN, OLED_LEFT_ROLL, + OLED_CLS); + P20 = 0; // 停止充电 +} \ No newline at end of file