From b3a74ab2f4c8386cad6b3222c8be9631209a4ea4 Mon Sep 17 00:00:00 2001 From: zouhaitao Date: Thu, 30 Jul 2026 15:25:44 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E5=94=A4=E9=86=92=E6=97=B6=E7=AB=8B?= =?UTF-8?q?=E5=8D=B3=E9=87=8D=E7=BD=AE=E6=89=80=E6=9C=89=E6=8C=89=E9=94=AE?= =?UTF-8?q?=E7=8A=B6=E6=80=81=E8=AE=A1=E6=95=B0=EF=BC=8C=E5=B9=B6=E5=B0=86?= =?UTF-8?q?=E5=85=A8=E5=B1=80=E4=B8=8E=E6=97=B6=E9=92=9F=E4=B8=AD=E6=96=AD?= =?UTF-8?q?=E7=9A=84=E5=BC=80=E5=90=AF=E6=8E=A8=E8=BF=9F=E8=87=B3=E5=B1=8F?= =?UTF-8?q?=E5=B9=95=E5=88=9D=E5=A7=8B=E5=8C=96=20Delay=20=E4=B9=8B?= =?UTF-8?q?=E5=90=8E=EF=BC=8C=E5=BD=BB=E5=BA=95=E8=A7=A3=E5=86=B3=E5=94=A4?= =?UTF-8?q?=E9=86=92=E7=9E=AC=E9=97=B4=E7=9A=84=20ADC=20=E7=94=B5=E5=8E=8B?= =?UTF-8?q?=E6=B3=A2=E5=8A=A8=E8=AF=AF=E5=88=A4=E5=AF=BC=E8=87=B4=E7=AB=8B?= =?UTF-8?q?=E9=A9=AC=E5=85=B3=E6=9C=BA=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- App/system.c | 201 +++++++++++++++++++++++++---------------------- woke-order/wo-01 | 4 +- 2 files changed, 110 insertions(+), 95 deletions(-) diff --git a/App/system.c b/App/system.c index 3b2abbf..2a91304 100644 --- a/App/system.c +++ b/App/system.c @@ -8,39 +8,39 @@ #include "../Drivers/pcf8563.h" #include "intrins.h" -// 引用 main.c 中的全局唤醒与运行状态变量 +// 引用 main.c 的全唤醒与运行状态变 extern volatile u8 p0_wakeup_flag; extern volatile u8 p2_wakeup_flag; extern volatile u8 p3_wakeup_flag; extern volatile u8 rf_wakeup_flag; /** - * @brief 系统 GPIO 端口模式初始化 - * @details 配置各引脚的推挽输出、高阻输入及准双向模式,建立系统初始电气环境。 + * @brief 系统 GPIO 口模式初始化 + * @details 配置各引脚的推挽输出、高阻输入及准双向模式,建立系统初电气环境 */ void GPIO_Init(void) { - // 使能访问扩展特殊功能寄存器 XSFR + // 使能访问扩展特殊功能寄存 XSFR EAXFR = 1; - // 1. 配置 PWR_HOLD (P0.0) 为推挽输出模式 (P0M1 bit0=0, P0M0 bit0=1) + // 1. 配置 PWR_HOLD (P0.0) 为推挽输出模 (P0M1 bit0=0, P0M0 bit0=1) P0M1 &= ~(1 << 0); P0M0 |= (1 << 0); - PWR_HOLD = 1; // 上电第一时间拉高,锁存电源保持供电 + PWR_HOLD = 1; // 上电时间拉高,锁存电源保持供 - // 2. 配置 KEY_UP (P0.1), KEY_CONFIRM (P0.2) 为高阻输入/带上拉准双向 + // 2. 配置 KEY_UP (P0.1), KEY_CONFIRM (P0.2) 为高阻输/带上拉准双向 P0M1 &= ~((1 << 1) | (1 << 2)); P0M0 &= ~((1 << 1) | (1 << 2)); KEY_UP = 1; KEY_CONFIRM = 1; - // 3. 初始化 STC32G 硬件 ADC 模块 (其中自动配置 P0.3 和 P1.3 为高阻输入模式) + // 3. 初化 STC32G ADC 模块 (其中动配 P0.3 P1.3 为高阻输入模) ADC_Init(); - // 4. 配置 PCF8563 I2C 管脚 P3.2 (SCL) 与 P3.3 (SDA) 为准双向口模式,并开上拉 + // 4. 配置 PCF8563 I2C 管脚 P3.2 (SCL) P3.3 (SDA) 为准双向口模式,并开上拉 P3M1 &= ~((1 << 2) | (1 << 3)); P3M0 &= ~((1 << 2) | (1 << 3)); - P3PU |= (1 << 2) | (1 << 3); // 开启 P3.2 与 P3.3 的内部 4.7K 上拉电阻 + P3PU |= (1 << 2) | (1 << 3); // P3.2 P3.3 的内 4.7K 上拉电阻 RTC_SCL = 1; RTC_SDA = 1; @@ -49,49 +49,49 @@ void GPIO_Init(void) P2M1 &= ~((1 << 5) | (1 << 3)); P2M0 |= ((1 << 5) | (1 << 3)); MOTOR = 0; - RGB_DIN = 0; // P2.3 初始拉低,防止上电期间 WS2812B 误触发 + RGB_DIN = 0; // P2.3 初拉低,防上电期间 WS2812B 触发 - // 配置 KEY_SOS (P2.6) 为带上拉准双向口模式以确保输入稳定 + // 配置 KEY_SOS (P2.6) 为带上拉准双向口模式以确保输入稳 P2M1 &= ~(1 << 6); P2M0 &= ~(1 << 6); KEY_SOS = 1; (*(unsigned char volatile xdata *)0xFE12) |= (1 << 6); // 使能 P2.6 的强内部上拉电阻 (P2PU = 0xFE12) - // SGM_CTRL (P1.7), LCD 控制管脚 (P1.0, P1.1, P1.4, P1.5, P1.6) 置为推挽输出 + // SGM_CTRL (P1.7), LCD 控制管脚 (P1.0, P1.1, P1.4, P1.5, P1.6) 为推挽输 P1M1 &= ~((1 << 7) | (1 << 0) | (1 << 1) | (1 << 4) | (1 << 5) | (1 << 6)); P1M0 |= ((1 << 7) | (1 << 0) | (1 << 1) | (1 << 4) | (1 << 5) | (1 << 6)); - // SHUT (P3.5) 射频/外设开启使能脚置为推挽输出 + // SHUT (P3.5) 射/外开使能脚置为推挽输 P3M1 &= ~(1 << 5); P3M0 |= (1 << 5); - SHUT = 0; // 低电平开启工作 + SHUT = 0; // 低电平开工作 // 7. 配置 CHRG_DET (P1.2) 为高阻输入模式,适配 DET 模拟 ADC 通道 2 - // 由于是精密模拟电平检测,切勿开启引脚内部上拉电阻 + // 由于精密模拟电平测,切勿引脚内部上拉电阻 P1M1 |= (1 << 2); P1M0 &= ~(1 << 2); - // P1PU 在扩展 XSFR 空间中没有被定义的话可以用 P1 端口寄存器或者是关闭上拉, - // STC32G 中端口上拉寄存器是 P1PU (FE11H),因为是 XSFR 我们在 config.h 里有 extern 或直接操作 - // 扩展 XSFR P1PU 地址为 0xFE11 + // P1PU 在扩 XSFR 空间没有定义的话以用 P1 口寄存器或是关闭上拉 + // STC32G 口上拉寄存器 P1PU (FE11H),因为是 XSFR 我们 config.h 里有 extern 或直接操 + // 扩展 XSFR P1PU 地址 0xFE11 (*(unsigned char volatile xdata *)0xFE11) &= ~(1 << 2); } /** - * @brief 初始化 UART1 串口通信 - * @details 设定波特率 115200 (使用 Timer2 作为发生器,24.0MHz 晶振) + * @brief 初化 UART1 串口通信 + * @details 设定波特 115200 (使用 Timer2 作为发生24.0MHz 晶振) */ void Uart1_Init(void) { - SCON = 0x50; // 8 位数据, 可变波特率 - AUXR |= 0x01; // 串口 1 选择 Timer2 做波特率发生器 - AUXR |= 0x04; // Timer2 时钟为 1T 模式 - T2L = 0xCC; // 24MHz / 115200 = 208 (0xD0), 对应 reload 值 65536 - 52 = 0xFFCC + SCON = 0x50; // 8 位数, 变波特率 + AUXR |= 0x01; // 串口 1 选择 Timer2 做波特率发生 + AUXR |= 0x04; // Timer2 时钟 1T 模式 + T2L = 0xCC; // 24MHz / 115200 = 208 (0xD0), 对应 reload 65536 - 52 = 0xFFCC T2H = 0xFF; - AUXR |= 0x10; // 启动 Timer2 运行 + AUXR |= 0x10; // Timer2 运 } /** - * @brief 串口 1 发送单字节数据 + * @brief 串口 1 发单字节数据 * @param dat 待发送的字节 */ void Uart_SendByte(u8 dat) @@ -102,8 +102,8 @@ void Uart_SendByte(u8 dat) } /** - * @brief 串口 1 发送字符串 - * @param s 字符串指针 + * @brief 串口 1 发字符串 + * @param s 字串指针 */ void Uart_SendString(char *s) { @@ -113,8 +113,8 @@ void Uart_SendString(char *s) } /** - * @brief 串口 1 非阻塞接收字符 - * @return char 接收到的字符,若无接收数据则返回 '\0' + * @brief 串口 1 非阻塞接收字 + * @return char 接收到的字,若无接收数据则返 '\0' */ char Uart_RxChar(void) { @@ -126,8 +126,8 @@ char Uart_RxChar(void) } /** - * @brief 阻塞毫秒延时 - * @param ms 毫秒数 + * @brief 阻秒延 + * @param ms 秒数 */ void Delay_ms(u16 ms) { @@ -140,8 +140,8 @@ void Delay_ms(u16 ms) } /** - * @brief 阻塞微秒延时 - * @param us 微秒数 + * @brief 阻微秒延 + * @param us 秒数 */ void Delay_us(u16 us) { @@ -152,8 +152,8 @@ void Delay_us(u16 us) } /** - * @brief 系统开机上电硬件自检函数 - * @details 检测 PWR_HOLD 锁存状态、ADC 采样基准与串口通讯,输出完整自检 report + * @brief 系统机上电硬件自函数 + * @details PWR_HOLD 锁存状ADC 采样基准与串口,输出完整自 report */ void Self_Test(void) { @@ -165,12 +165,12 @@ void Self_Test(void) Uart_SendString("\r\n========================================\r\n"); Uart_SendString("[SELF-TEST] System Power-On Self Test...\r\n"); - // 执行 I2C 总线器件扫描,查找 RTC 是否物理响应 + // 执 I2C 总线器件描,查找 RTC 否物理响 PCF8563_ScanDiagnostic(); - // 0. I2C 硬件脚电平诊断测试 (验证引脚可控性与短路) + // 0. I2C 件脚电平诊断测试 (验证引脚控与) Uart_SendString("[I2C-DIAG] Pin Level Test Starting...\r\n"); - // 写 1 测试 (准双向+上拉) + // 1 测试 (准双+上拉) P3M1 &= ~((1 << 2) | (1 << 3)); P3M0 &= ~((1 << 2) | (1 << 3)); P3PU |= (1 << 2) | (1 << 3); @@ -183,7 +183,7 @@ void Self_Test(void) Uart_SendByte((u8)(RTC_SDA ? '1' : '0')); Uart_SendString("\r\n"); - // 写 0 测试 + // 0 测试 RTC_SCL = 0; RTC_SDA = 0; Delay_ms(10); @@ -193,17 +193,17 @@ void Self_Test(void) Uart_SendByte((u8)(RTC_SDA ? '1' : '0')); Uart_SendString("\r\n"); - // 0.2 执行 RTC 底层单独试读测试 + // 0.2 执 RTC 底层单独试测 PCF8563_TryReadDiagnostic(); - // 1. 验证 PWR_HOLD 锁存状态 + // 1. 验证 PWR_HOLD 锁存状 if (PWR_HOLD == 1) { Uart_SendString("[SELF-TEST] PWR_HOLD Pin State: HIGH [OK]\r\n"); } else { Uart_SendString("[SELF-TEST] PWR_HOLD Pin State: LOW [FAIL]\r\n"); } - // 2. 检查 P0.3 ADC 按键基准常态电压 + // 2. P0.3 ADC 按键基准常电 key_down_adc = ADC_ReadFiltered(ADC_CHANNEL_KEY_DOWN); Uart_SendString("[SELF-TEST] KEY_DOWN (P0.3) ADC Raw Value: "); Uart_SendByte((u8)('0' + (key_down_adc / 1000) % 10)); @@ -212,12 +212,12 @@ void Self_Test(void) Uart_SendByte((u8)('0' + (key_down_adc % 10))); Uart_SendString(" [OK]\r\n"); - // 2.2 检测 KEY_SOS (P2.6) 物理电平常态 + // 2.2 KEY_SOS (P2.6) 物理电平常 Uart_SendString("[SELF-TEST] KEY_SOS (P2.6) Pin Level: "); Uart_SendByte((u8)(KEY_SOS ? '1' : '0')); Uart_SendString("\r\n"); - // 3. 检查 P1.3 电池电压检测与百分比 + // 3. P1.3 电池电压测与百分 vbat_mv = ADC_GetBatteryVoltage_mV(); percent = ADC_GetBatteryPercent(); batt_adc_raw = ADC_ReadFiltered(ADC_CHANNEL_BATTERY); @@ -240,7 +240,7 @@ void Self_Test(void) Uart_SendByte((u8)('0' + (percent % 10))); Uart_SendString("% [OK]\r\n"); - // 4. 检查充电状态 + // 4. 查充电状 { u16 det_adc = ADC_ReadFiltered(ADC_CHANNEL_CHRG_DET); u16 det_mv = (det_adc * 3300UL) / 4095UL; @@ -269,93 +269,93 @@ void Self_Test(void) } /** - * @brief 执行关机断电流程 - * @details 关断外设、震动提示并拉低 PWR_HOLD 引脚切断总电源 + * @brief 执关机断电流 + * @details 关断外震动提示并拉低 PWR_HOLD 引脚切断总电 */ void Power_Off(void) { Uart_SendString("[SYS] Executing Power Off sequence...\r\n"); - // 马达震动反馈 100ms + // 达震动反 100ms MOTOR = 1; Delay_ms(100); MOTOR = 0; - // 关断屏幕背光与 RGB 灯光 - SGM_CTRL = 1; // 高电平断电,关闭背光灭屏 + // 关断屏幕背光 RGB + SGM_CTRL = 1; // 高电平断电,关闭背光 RGB_Send(0, 0, 0, 0, 0, 0); - // 拉低 PWR_HOLD 切断电源锁存使总电源关闭 + // 拉低 PWR_HOLD 切断电源锁存使电源关 PWR_HOLD = 0; - // 进入死循环等待电源物理切断 + // 进入死循等待电源物理切断 while (1) { PWR_HOLD = 0; } } /** - * @brief 系统切入低功耗停机休眠模式 + * @brief 系统切入低功耗停机休眠模 */ void Enter_Low_Power_Sleep(void) { Uart_SendString("[SYS] Entering low power sleep...\r\n"); - // 1. 关闭/熄灭 RGB 灯 + // 1. 关闭/熄灭 RGB RGB_Send(0, 0, 0, 0, 0, 0); - // 2. 向 LCD 芯片写入 Display OFF 指令 (0x28) 关显示 + // 2. LCD 片写 Display OFF 指令 (0x28) 关显 WriteComm(0x28); Delay_ms(20); - // 3. 向 LCD 芯片写入 Sleep In 指令 (0x10) 关内部电荷泵 + // 3. LCD 片写 Sleep In 指令 (0x10) 关内部电荷泵 WriteComm(0x10); Delay_ms(20); - // 4. 关闭背光(高电平断电,关闭背光灭屏) + // 4. 关闭背光(高电平电,关闭背光屏) SGM_CTRL = 1; - // 5. 屏幕接口防漏电处理 + // 5. 屏幕接口防漏电理 LCD_CS = 1; LCD_RST = 1; LCD_DCX = 0; LCD_SCL = 0; LCD_SDI = 0; - // 6. 射频设置为关闭接收模式(低功耗,SHUT=0, RF_SetMode(0)) + // 6. 射置为关接收模式(低功,SHUT=0, RF_SetMode(0) RF_SetMode(0); - // 使能访问扩展特殊功能寄存器 + // 使能访问扩展特殊功能寄存 P_SW2 |= 0x80; - // 7. 配置 Port0 中断唤醒源 (KEY_UP=P0.1, KEY_CONFIRM=P0.2, KEY_DOWN=P0.3) + // 7. 配置 Port0 唤醒 (KEY_UP=P0.1, KEY_CONFIRM=P0.2, KEY_DOWN=P0.3) P0IM1 |= 0x0E; - P0IM0 &= ~0x0E; // 下降沿触发 - P0INTF = 0x00; // 清除挂起的中断标志 - P0INTE |= 0x0E; // 开启 P0.1, P0.2, P0.3 中断允许 + P0IM0 &= ~0x0E; // 下降沿触 + P0INTF = 0x00; // 清除挂起的中标志 + P0INTE |= 0x0E; // P0.1, P0.2, P0.3 允 P0WKUE |= 0x0E; // 使能 P0.1, P0.2, P0.3 掉电唤醒 - // 8. 配置 Port2 中断唤醒源 (SOS=P2.6) + // 8. 配置 Port2 唤醒 (SOS=P2.6) P2IM1 |= 0x40; - P2IM0 &= ~0x40; // 下降沿触发 + P2IM0 &= ~0x40; // 下降沿触 P2INTF = 0x00; // 清除挂起标志 - P2INTE |= 0x40; // 开启 P2.6 中断允许 + P2INTE |= 0x40; // P2.6 允 P2WKUE |= 0x40; // 使能 P2.6 掉电唤醒 - // 9. 配置 Port3 中断唤醒源 (RF_RX_DATA=P3.6) + // 9. 配置 Port3 唤醒 (RF_RX_DATA=P3.6) P3IM1 |= 0x40; - P3IM0 |= 0x40; // 双边沿触发 + P3IM0 |= 0x40; // 双边沿触 P3INTF = 0x00; // 清除挂起标志 - P3INTE |= 0x40; // 开启 P3.6 中断允许 + P3INTE |= 0x40; // P3.6 允 P3WKUE |= 0x40; // 使能 P3.6 掉电唤醒 - // 确保引脚上拉和输入使能,防止因浮空产生的功耗泄漏 + // 保引脚上拉和输入使能,防止因空产生的功泄 P2PU |= 0x40; P2IE |= 0x40; P3PU &= ~0x40; P3IE |= 0x40; - // 清零各个唤醒检测标志位 + // 清零各个唤醒测标志位 P0INTF = 0x00; P2INTF = 0x00; P3INTF = 0x00; @@ -365,25 +365,38 @@ void Enter_Low_Power_Sleep(void) p3_wakeup_flag = 0; rf_wakeup_flag = 0; - // 10. 关闭系统滴答定时器 Timer1 中断,防止休眠时被定时器误唤醒 + // 10. 关闭系统滴答定时 Timer1 ,防休眠时定时器唤醒 ET1 = 0; - EA = 1; // 开启全局中断 + EA = 1; // 全局 // 配置 PCON 挂起单片机,切入停机 (Power Down) 模式 PCON |= 0x02; // PD = 1 _nop_(); _nop_(); _nop_(); _nop_(); - // ====== 被外部中断唤醒后,在此处继续运行 ====== + // ====== 外部唤醒后,在继运 ====== Wakeup_Restore(); } /** - * @brief 休眠唤醒恢复 + * @brief 休眠唤醒恢 */ void Wakeup_Restore(void) { + // ò㰴״̬ϵ/˲̬³ػ + extern volatile u16 key_up_hold; + extern volatile u16 key_down_hold; + extern volatile u16 key_confirm_hold; + extern volatile u16 key_sos_hold; + extern volatile u16 comb_hold; + + key_up_hold = 0; + key_down_hold = 0; + key_confirm_hold = 0; + key_sos_hold = 0; + comb_hold = 0; + EAXFR = 1; - // 1. 立即关闭所有掉电外部中断允许与唤醒允许,防止重入 + // 1. 立即关闭有掉电部允与唤醒允,防重 P0INTE = 0x00; P2INTE = 0x00; P3INTE = 0x00; @@ -394,15 +407,14 @@ void Wakeup_Restore(void) P2INTF = 0x00; P3INTF = 0x00; - // 2. 清零掉电唤醒定时器 + // 2. 清零掉电唤醒定时 WKTCH = 0x00; WKTCL = 0x00; - // 3. 开启全局中断并重启系统滴答定时器 - EA = 1; - ET1 = 1; + // 3. 全局并重系统滴答定时 + // 3. жϿ״̬ƳĻʼ֮ - // 4. 恢复射频芯片工作模式 + // 4. 恢射频芯片工作模 RF_SetMode(1); // 打印唤醒调试日志 @@ -419,19 +431,22 @@ void Wakeup_Restore(void) Uart_SendString("[WR] Woken by TIMER/Other\r\n"); } - // 5. 恢复屏幕供电与背光(低电平上电,恢复背光亮屏) + // 5. 恢屏幕供电与背光(低电平上电,恢复背光亮屏) SGM_CTRL = 0; - // 6. 延时 200ms 等待液晶稳压板上电稳定后,重新对 LCD 寄存器初始化 + // 6. 延时 200ms 等待液晶稳压板上电稳定后,重新 LCD 寄存器初始化 Delay_ms(200); LCD_Init(); - // 7. 充零闲置计时器 + // ¿ȫж Timer1 δʱжϣȷڵѹȶſʼ + EA = 1; + ET1 = 1; + // 7. 充零闲置计时 inactivity_timer = 0; } /** - * @brief 安全获取 Timer0 计数器值 (防高字节滚动跳变) + * @brief 安全获取 Timer0 计数器 (防高字节滚动跳变) */ u16 GetTimer0_Safe(void) { @@ -445,7 +460,7 @@ u16 GetTimer0_Safe(void) } /** - * @brief 串口 1 发送 4 位十六进制字符 (0x0~0xF) + * @brief 串口 1 发 4 位十进制字 (0x0~0xF) */ void Uart_SendHex4(u8 val) { @@ -458,7 +473,7 @@ void Uart_SendHex4(u8 val) } /** - * @brief 串口 1 发送 8 位十六进制 (0x00~0xFF) + * @brief 串口 1 发 8 位十进制 (0x00~0xFF) */ void Uart_SendHex8(u8 val) { @@ -467,7 +482,7 @@ void Uart_SendHex8(u8 val) } /** - * @brief 串口 1 发送 16 位十六进制 (0x0000~0xFFFF) + * @brief 串口 1 发 16 位十进制 (0x0000~0xFFFF) */ void Uart_SendHex16(u16 val) { @@ -476,7 +491,7 @@ void Uart_SendHex16(u16 val) } /** - * @brief 串口 1 发送 20 位十六进制 (用于射频 5 位 ID 打印) + * @brief 串口 1 发 20 位十进制 (用于射 5 ID 打印) */ void Uart_SendHex20(u32 val) { @@ -485,7 +500,7 @@ void Uart_SendHex20(u32 val) } /** - * @brief 串口 1 发送 32 位十六进制 + * @brief 串口 1 发 32 位十进制 */ void Uart_SendHex32(u32 val) { diff --git a/woke-order/wo-01 b/woke-order/wo-01 index df92837..f9e5e45 100644 --- a/woke-order/wo-01 +++ b/woke-order/wo-01 @@ -10,8 +10,8 @@ 根据项目开发优先级与依赖关系,按以下四个顺序阶段分步完成: -### 阶段 1: P0.3 ADC 按键检测 -- **硬件引脚**: `P0.3` 对应 STC32G 硬件 `ADC3` 通道。 +### 阶段 1: P0.3 ADC 按键检测c +- **硬件引脚**: `P0.3` 对应 STC32G 硬件 `ADC11` 通道。 - **电平特征**: 开机常态下 `KEY_DOWN` 节点电压约为 **2.0V**(未按下),按键按下后电压升至约为 **3.7V**。 - **算法与逻辑**: - 配置 ADC 模块,引入滑动窗口均值/中值滤波消抖。