feat: 校准电池电压与ADC2充电检测,重构RGB为Bitbang翻转驱动,并修复RTC晶振起振问题

This commit is contained in:
2026-07-28 18:03:20 +08:00
parent 47bcd252b2
commit d01121e3ae
25 changed files with 15134 additions and 11463 deletions

View File

@@ -4,12 +4,13 @@
#include "system.h"
#include "clock.h"
#include "xtell.h"
#include "../Drivers/adc.h"
// 定义事件环形队列的最大深度为 8
#define EVENT_QUEUE_DEPTH 8
// 环形队列存储数组 (存放在单片机 idata 快速RAM区中)
static SystemEvent idata event_queue[EVENT_QUEUE_DEPTH];
// 环形队列存储数组 (存放在单片机 xdata 拓展 RAM区中)
static SystemEvent xdata event_queue[EVENT_QUEUE_DEPTH];
static u8 queue_head = 0; // 队首读指针
static u8 queue_tail = 0; // 队尾写指针
static u8 queue_count = 0; // 当前队列内有效事件总数
@@ -130,6 +131,12 @@ void Event_Dispatcher_Loop(void)
return;
}
// 关机事件处理:捕获到长按关机指令,直接调用 Power_Off 关断电源
if (evt.key_event == KEY_EVENT_POWER_OFF) {
Power_Off();
return;
}
// 常规事件(如普通的按键点击)直接透传分发给当前处于前台活跃的应用
AppManager_DispatchEvent(evt);
}
@@ -152,31 +159,57 @@ void Timer1_Init(void)
EA = 1; // 开启全局中断允许
}
// 全局按键扫描触发标志
volatile bit key_scan_flag = 0;
/**
* @brief 定时器 1 中断服务程序 (每 1ms 触发一次)
* @details 承担系统软时钟计算10ms 周期性按键消抖扫描的功能。马达等特定业务已剥离至 App 内部
* @details 承担系统软时钟计算,并每 10ms 置位主循环按键扫描标志,不直接在中断中进行 ADC 多次采样
*/
void Timer1_Isr(void) interrupt 3
{
SystemEvent evt;
// 1ms 定时更新软时钟
Clock_IncMS();
// 报警屏幕红边框以 100ms 周期亮灭,进行颜色爆闪指示
alarm_flash_flag = (ms_tick / 100) % 2;
/* 物理按键扫描及消抖状态机逻辑 (每 10ms 轮询一次) */
/* 物理按键定时计数 (每 10ms 置位一次标志位) */
key_scan_timer++;
if (key_scan_timer >= 10) {
// 读取按键的电平信号 (由于有上拉电阻,未按下为高 1按下为低 0所以取反做正逻辑)
u8 raw_up = !KEY_UP;
u8 raw_down = !KEY_DOWN;
u8 raw_confirm = !KEY_CONFIRM;
u8 raw_sos = 0; // 临时注释关闭 SOS 物理按键电平检测,防浮空干扰
key_scan_timer = 0; // 重置扫描分频计数器
key_scan_flag = 1; // 仅在中断里置起标志位,留待主循环中执行实际读取与消抖
}
}
// 检测到有任意按键处于下压状态,立即将无操作闲置休眠计时器归零
/**
* @brief 主循环按键扫描与消抖处理函数
* @details 由主循环每 10ms 检查并执行,完全在主线程中运行,绝无中断重入冲突。
*/
void Event_KeyScan_Poll(void)
{
SystemEvent evt;
// 读取按键的电平信号 (KEY_UP, KEY_CONFIRM 为低电平有效)
u8 raw_up = !KEY_UP;
u8 raw_down = ADC_IsKeyDown(); // KEY_DOWN 通过 P0.3 ADC 通道判定 (常态 2.0V, 按下 3.7V)
u8 raw_confirm = !KEY_CONFIRM;
u8 raw_sos = 0; // 临时注释关闭 SOS 物理按键电平检测,防浮空干扰
key_scan_timer = 0; // 重置扫描分频计数器
// 按键调试诊断:若按键 ADC 值有变化或处于高电平,串口输出真实 ADC 值
{
u16 down_val = ADC_ReadFiltered(ADC_CHANNEL_KEY_DOWN);
if (down_val > 2800) {
Uart_SendString("[KEY-DIAG] KEY_DOWN pressed! ADC Raw: ");
Uart_SendByte((u8)('0' + (down_val / 1000) % 10));
Uart_SendByte((u8)('0' + (down_val / 100) % 10));
Uart_SendByte((u8)('0' + (down_val / 10) % 10));
Uart_SendByte((u8)('0' + (down_val % 10)));
Uart_SendString("\r\n");
}
}
// 检测到有任意按键处于下压状态,立即将无操作闲置休眠计时器归零
if (raw_up || raw_down || raw_confirm || raw_sos) {
inactivity_timer = 0;
} else {
@@ -219,15 +252,16 @@ void Timer1_Isr(void) interrupt 3
key_up_hold = 0; // 释放归零
}
// ▼ (KEY_DOWN) 按键状态机
// ▼ (KEY_DOWN / 开关机) 按键状态机
if (raw_down) {
key_down_hold++;
if (key_down_hold == 300) { // 长按 3
evt.key_event = KEY_EVENT_DOWN_LONG;
if (key_down_hold == 100) { // 长按 1 (100 * 10ms = 1000ms = 1s) 触发关机事件
evt.key_event = KEY_EVENT_POWER_OFF;
EventQueue_Push(evt);
}
} else {
if (key_down_hold >= 2 && key_down_hold < 300) {
// 如果松开时按下时长在 20ms 至 1s 之间,触发短按下翻/选择事件
if (key_down_hold >= 2 && key_down_hold < 100) {
evt.key_event = KEY_EVENT_DOWN_CLICK;
EventQueue_Push(evt);
}
@@ -266,5 +300,4 @@ void Timer1_Isr(void) interrupt 3
}
*/
}
}
}