From 8bf68e256d06133f678d3fd0cc5b8bb3aedffc3f Mon Sep 17 00:00:00 2001 From: yuquanjun Date: Sat, 26 Sep 2026 15:06:36 +0800 Subject: [PATCH] fix(pwr): shut down at 6.8V and light the charge page only above it Co-authored-by: Cursor --- APP/app_adc.c | 57 ++++++++++++++++++++++++++++++++++++------------- APP/app_adc.h | 2 ++ Global/Global.c | 4 ++-- UI/UI_Idle.c | 12 +++++++++++ 4 files changed, 58 insertions(+), 17 deletions(-) diff --git a/APP/app_adc.c b/APP/app_adc.c index 705e560..96d4059 100644 --- a/APP/app_adc.c +++ b/APP/app_adc.c @@ -355,6 +355,16 @@ static void app_adc_volume_process(void) +static uint16_t s_vbat_raw = 0; +static uint8_t s_vbat_valid = 0; +static uint8_t s_charge_ui_allowed = 0; + +/* 高于 6.8V 才允许点亮关机充电页;未采样视为不允许 */ +uint8_t app_adc_charge_ui_allowed(void) +{ + return (s_vbat_valid && s_vbat_raw > (uint16_t)VBAT_SHUTDOWN_RAW) ? 1u : 0u; +} + static bat_state_t bat_state = BAT_IDLE; static uint32_t bat_last_sample_tick = 0; /* 上次采样时刻 */ static uint32_t bat_state_tick = 0; /* 进当前状态的时刻 */ @@ -383,6 +393,9 @@ void app_adc_init(void) bat_poweron_done = 0; bat_sample_cnt = 0; bat_sample_tick = 0; + s_vbat_raw = 0; + s_vbat_valid = 0; + s_charge_ui_allowed = 0; } /* 采样:读 ADC + 滑动平均 */ @@ -396,11 +409,14 @@ static void app_adc_battery_do_sample(void) bat_index = (bat_index + 1) % BAT_SAMPLE_COUNT; } -/* 上报:映射成百分比,变化才发消息;低于 6.8V 触发低电量关机(插着 Type-C 也执行) */ +/* 上报:映射成百分比,变化才发消息;低于等于 6.8V 触发低电量关机(插着 Type-C 也执行) */ static void app_adc_battery_report(void) { uint16_t filtered = bat_sum / BAT_SAMPLE_COUNT; uint8_t pct; + uint8_t allow; + uint8_t pct_changed; + uint8_t allow_changed; if (filtered < VBAT_MIN_RAW) pct = 0; @@ -409,26 +425,33 @@ static void app_adc_battery_report(void) else pct = (uint8_t)(100 * (filtered - VBAT_MIN_RAW) / (VBAT_MAX_RAW - VBAT_MIN_RAW)); - /* 开机使用中包电压低于 6.8V:停负载并关机。插着 Type-C 同样执行,避免边充边用拉过保护电压 */ - if (powon && !System_LowBat_IsActive() && - filtered < (uint16_t)VBAT_SHUTDOWN_RAW) + allow = (filtered > (uint16_t)VBAT_SHUTDOWN_RAW) ? 1u : 0u; + s_vbat_raw = filtered; + s_vbat_valid = 1u; + + /* 开机使用中包电压低于等于 6.8V:提示页停留 10s 后关机。插着 Type-C 同样停负载 */ + if (powon && !System_LowBat_IsActive() && allow == 0u) { LOG_W("BAT", "lowbat raw=%u thr=%u → tip+shutdown", (unsigned)filtered, (unsigned)VBAT_SHUTDOWN_RAW); MainTask_Sendmsg(MSG_ID_LOW_BAT_TIP, pct, filtered, 0); } - if (pct != percentage) { /* 变化才上报 */ + pct_changed = (pct != percentage) ? 1u : 0u; + allow_changed = (allow != s_charge_ui_allowed) ? 1u : 0u; + s_charge_ui_allowed = allow; + if (pct_changed) percentage = pct; - if(usb_charging_state && !powon) - { - MainTask_Sendmsg(MSG_ID_POWOFF_CHARG, percentage, usb_charging_state, 0); - } - else - { - MainTask_Sendmsg(MSG_ID_BATTERY_VALUE, percentage, usb_charging_state, 0); - } - + + if (usb_charging_state && !powon) + { + /* 跨过 6.8V 也要通知,否则百分比不变时充电页不会亮或熄 */ + if (pct_changed || allow_changed) + MainTask_Sendmsg(MSG_ID_POWOFF_CHARG, percentage, usb_charging_state, 0); + } + else if (pct_changed) + { + MainTask_Sendmsg(MSG_ID_BATTERY_VALUE, percentage, usb_charging_state, 0); } } @@ -450,9 +473,13 @@ static void app_adc_battery_process(void) { uint32_t interval = BAT_SAMPLE_INTERVAL_MS; uint16_t last_avg = bat_sum / BAT_SAMPLE_COUNT; - /* 关机充电不加快采样,避免每 2 秒停一次充电 */ + /* 开机接近低电时加快采样。关机充电且尚未高于 6.8V 也加快, + * 但不停充电芯片,便于电压回升后尽快点亮充电页。 */ if (powon && last_avg != 0 && last_avg < (uint16_t)VBAT_FAST_SAMPLE_RAW) interval = BAT_SAMPLE_INTERVAL_LOW_MS; + else if (!powon && usb_charging_state && s_vbat_valid && + s_vbat_raw <= (uint16_t)VBAT_SHUTDOWN_RAW) + interval = BAT_SAMPLE_INTERVAL_LOW_MS; if (now - bat_last_sample_tick >= interval) bat_state = BAT_START; } diff --git a/APP/app_adc.h b/APP/app_adc.h index 9e67e8e..e9e4d72 100644 --- a/APP/app_adc.h +++ b/APP/app_adc.h @@ -22,6 +22,8 @@ extern bool pick_hold_up; extern bool usb_charging_state; extern bool usb_charging_laststate; extern uint8_t percentage; +/* ¹ػú³äµçҳ£º½öµ±ÒѲɵ½µİüµçѹ¸ßÓÚ 6.8V ʱΪ 1¡£δ²ÉÑù»òµÍÓڵÈÓÚ 6.8V Ϊ 0¡£ */ +uint8_t app_adc_charge_ui_allowed(void); void app_adc_scan_all(void); void app_adc_in1_scan_part(uint8_t channel); bool app_adc_usb_is_plugged(void); diff --git a/Global/Global.c b/Global/Global.c index 46b5bbe..eecf654 100644 --- a/Global/Global.c +++ b/Global/Global.c @@ -204,7 +204,7 @@ static volatile uint8_t s_pwr_rails_cut = 0; /* TMR7:关机长按已触发请求后的紧急倒计时(ms) */ static volatile uint16_t s_pwr_off_grace_ms = 0; -/* 电量 <6.8V:提示界面停留后关机(插着 Type-C 也停负载) */ +/* 电量 <=6.8V:提示界面停留后关机(插着 Type-C 也停负载) */ #define LOWBAT_SHUTDOWN_DELAY_MS 10000u static volatile uint8_t s_lowbat_active = 0; static volatile uint32_t s_lowbat_deadline_ms = 0; @@ -438,7 +438,7 @@ void System_PowerOff_Poll(void) } } -/* 电量 <6.8V:提示界面停留后关机(插着 Type-C 也停负载) */ +/* 电量 <=6.8V:提示界面停留 10s 后关机(插着 Type-C 也停负载) */ void System_LowBat_Arm(void) { if (s_lowbat_active) diff --git a/UI/UI_Idle.c b/UI/UI_Idle.c index dffe70e..166880d 100644 --- a/UI/UI_Idle.c +++ b/UI/UI_Idle.c @@ -257,6 +257,18 @@ void IdleProcess(DisplayTaskMessage_Type msg) /* 已开机:忽略滞后的关机充电消息,勿覆盖模式选择页或切断主电 */ if (powon) break; + if (usb_charging_state && !app_adc_charge_ui_allowed()) + { + /* Type-C 充电且包电压未高于 6.8V:不点亮、不画充电页 */ + LCD_BLK_Clr(); + LCD_WR_REG(0x28); + if (s_charge_ui_drawn) + LCD_FillByColor(0, 0, 240, 320, BLACK); + s_charge_ui_drawn = false; + BSP_MainPowerEnable(0); + LOG_I("UI", "type-c charge <=6.8V, lcd off"); + break; + } if(!s_charge_ui_drawn) { uint8_t peek[4];