Skip to content

CH592F 电池 ADC、充电状态与 BLE 状态修复 ​

本文记录 adc_fix 分支相对于原作者基线提交 3fb545b 的全部改动、设计依据、协议兼容性和验证结果。

完整修改日志(简版) ​

部分简短描述
CHRG 硬件检测启用 PA13,读取 TP4054 的 CHRG 开漏状态,不再固定上报“未充电”。
充电状态消抖每 100ms 读取 CHRG;普通状态下连续低电平约 300ms 进入充电,连续高电平约 10s 退出充电。
满电维护充电满电后高电平稳定约 1s 即显示“未充电”,并忽略 TP4054 因板载负载产生的短暂补充充电脉冲。
ADC 配置按 WCH 官方参考改用 SampleFreq_3_2 + ADC_PGA_0,修正原来的 PGA 配置。
电压换算按 1.05V 参考电压和 100kΩ/100kΩ 分压计算电池电压,替换经验满量程公式。
ADC 共享保护采样前保存并重设 ADC,采样后恢复配置,避免 BLE 温度检测覆盖电池 ADC 通道和增益。
单次采样滤波丢弃首次转换,10 次采样去掉最大值和最小值,再对剩余结果求平均。
跨周期滤波使用 3:1 低通滤波;超过 250mV 的跳变需要第二组采样在 80mV 内复核。
电量算法删除原作者从 60% 开始按时间增长的模拟算法,改用单节 LiPo 电压曲线实时估算。
充电电压补偿充电估算时减去 40mV,降低 TP4054 充电端电压抬升造成的电量高估。
满电锁存4.16V 以上连续 3 次有效采样显示 100%;4.10V 以下连续 2 次才解除,避免高压区反复跳变。
分压供电策略KBD_VBAT_DIVIDER_ALWAYS_ON=0,仅在采样时开启 PA15 分压;ADC 模拟域保持开启,维修时仍可通过 ADC/HID 诊断判断主控工作状态。
HID 诊断字段在 SYS_STATUS 和 BATTERY 中增加 ADC 原始值和 CHRG 瞬时原始值,同时兼容旧响应长度。
Studio BLE 状态修正连接状态映射,状态值 2 正确显示“BLE 已连接”,状态值 1 显示“BLE 广播中”。
Studio 协议解析扩展电池与系统状态类型,解析并显示 ADC、CHRG 原始值,保留旧固件兼容性。
自动化测试增加扩展字段、旧协议兼容和 BLE 状态回归测试;Studio 共 70 条测试通过。
文档更新 HID 协议、电池算法、诊断方法、已知限制和本修改日志。

问题背景 ​

五键无线版实机调试中观察到以下问题:

  1. 电池分压点和 PA14 电压稳定,但 ADC 会在约 2757 与 1620 之间跳变,显示电压随之从约 4.20V 跳到 3.32V。
  2. 充电时电压从约 4.06V 上升到 4.11V,电量却只从 60% 增加到 62%。
  3. TP4054 正在充电时,Studio 不能直接看到 ADC 和 CHRG 引脚原始值,硬件与软件读数不便对照。
  4. 键盘已经通过 BLE 正常打字,但 Studio 调试终端仍显示“BLE 未连接”。

参考依据 ​

本次 ADC 修改没有自行猜测 CH592 的换算方式,主要参考仓库内已有的 WCH 官方资料:

  • CH592 数据手册:examples/openwch-ch592/Datasheet/CH592DS1_zh.PDF
  • WCH 无线鼠标外部分压采样:examples/openwch-ch592/Application/8K_PollingRateWirelessMouse/software/8K_PollingRate/8k_3mode_592/BLE/3mode_2_4G/APP/mouse.c
  • WCH ADC 驱动与粗校准实现:examples/openwch-ch592/EVT/EXAM/SRC/StdPeriphDriver/CH59x_adc.c

官方参考使用外部单端 ADC、SampleFreq_3_2、ADC_PGA_0,并按 ADC * 1050 / 2048 计算 ADC 输入电压。本板使用 100kΩ/100kΩ 二分之一分压,因此电池电压换算为:

text
VBAT_mV = (ADC原始值 + ADC粗校准值) * 1050 * 2 / 2048

相对原作者版本的改动 ​

1. 启用真实充电状态检测 ​

原版本将 KBD_HAS_CHARGE_DET 设为 0,因此 PA13 上 TP4054 的 CHRG 状态不会参与上报。

当前版本:

  • 将 KBD_HAS_CHARGE_DET 设为 1。
  • PA13 配置为内部上拉输入。
  • CHRG=0 表示 TP4054 开漏输出拉低,当前正在充电。
  • CHRG=1 表示 TP4054 当前没有拉低引脚。

CHRG 高电平不能区分“没有接入 VBUS”和“已经充电结束”。本板没有独立 VBUS 检测输入,因此固件不会仅凭 CHRG 从低变高就强制显示 100%。

充电末段实测发现 CHRG 会在数秒内反复切换,直接读取会让 RGB 在充电色和 BLE 连接色之间跳变。因此稳定状态每 100ms 采样一次:连续低电平约 300ms 后确认充电,连续高电平约 10s 后确认退出。HID 中的充电状态和 RGB 使用稳定结果,charge_pin_raw 仍输出瞬时电平用于观察 TP4054 的实际行为。

实测样板的满充平台约为 4.17~4.18V,不能要求每块板都达到标称 4.20V 才显示满电。电压达到 4.16V 后需连续 3 次有效采样确认,随后锁定显示 100%;只有电压降到 4.10V 以下并连续确认 2 次才解除满电。该回差策略可避免高压区在 98%~100% 之间反复跳变,同时不会由单次 ADC 毛刺触发满电。

满电区实测还会出现“CHRG 大部分时间为高,间歇短暂拉低”的维护充电现象。如果继续要求高电平连续 10s,低脉冲会不断清零退出计时,使界面长期显示“100% 充电中”。满电锁存后改为 CHRG 高电平稳定约 1s 即显示“100% 未充电”,并在锁存期间忽略短低脉冲;电压跌出满电回差区后才恢复普通充电判定。

2. 修正 ADC PGA 与电压公式 ​

项目原作者版本adc_fix
ADC 模式外部单端外部单端
采样频率SampleFreq_3_2SampleFreq_3_2
PGAADC_PGA_1_4,-12dBADC_PGA_0,0dB
电压公式ADC * 4200 / 2048ADC * 1050 * 2 / 2048
分压比隐含在经验满量程中明确为 100kΩ/100kΩ = 1/2
ADC 粗校准限制在 +/-64使用官方粗校准,异常值限制在 +/-256

新的公式能直接解释 ADC 原始值与万用表电压之间的关系,不再依赖板级经验满量程常量。

3. 解决 BLE 温度检测覆盖电池 ADC 配置 ​

BLE 温度校准与电池检测共用 CH592 ADC。原版本在使能分压后立即配置 ADC,随后等待分压稳定;等待期间 BLE 回调可能切换 ADC 通道或 PGA,导致电池转换使用了错误配置。

当前版本:

  1. 分压稳定等待期间不保留电池 ADC 配置。
  2. 真正转换前保存 ADC 通道、ADC 配置、PGA 增益位和 TouchKey 配置。
  3. 在短暂中断保护窗口内重新配置 PA14/AIN4 并完成采样。
  4. 转换结束后恢复共享外设原状态。

这项修改解决了硬件分压点稳定、软件 ADC 却从约 2757 跳到 1620 的问题。

4. 重新设计电压采样与滤波 ​

原版本等待 5ms,丢弃第一次转换后对 8 次结果做普通平均,没有跨周期滤波和异常跳变复核。

当前版本:

  • 分压稳定时间增加到 30ms。
  • 丢弃第一次转换。
  • 连续采样 10 次,去掉一个最大值和一个最小值,对剩余 8 次求平均。
  • 第一次有效结果直接采用;后续按“旧值权重 3、新值权重 1”进行低通滤波。
  • 合理电压范围限制为 2.50V 至 4.40V。
  • 相对缓存电压跳变超过 250mV 时立即再采一组。
  • 两组结果相差不超过 80mV 才接受大幅变化,否则丢弃本次瞬态干扰。
  • ADC 原始平均值保留给诊断协议,显示电压使用校准和滤波后的结果。

5. 重新设计电量估算 ​

原作者版本在检测到充电后:

  • 首次电量最高限制为 60%。
  • 每 30 秒采样一次。
  • 每 4 次采样增加 1%,约每两分钟增加 1%。
  • 充电中最高显示 98%。

该逻辑是按时间模拟充电进度,没有根据实时电压重新估算,因此会出现 4.11V 仍显示约 62%。

当前版本删除计时增长逻辑,改为:

  1. 使用单节 LiPo 分段电压曲线估算百分比。
  2. 充电时先从端电压减去 40mV,减轻 TP4054 充电电流造成的电压抬升。
  3. 普通充电估算最高限制为 99%,高压区连续确认满足满电锁存条件后才允许显示 100%。
  4. 4.16V 以上连续 3 次有效采样锁定 100%,4.10V 以下连续 2 次才解除。
  5. 百分比加入 1% 迟滞,减少曲线边界附近来回跳动。

例如充电状态下显示电压约 4.11V 时,估算使用约 4.07V,电量约为 93%,不再从固定的 60% 按时间缓慢增加。

此结果仍是电压估算,不是精确 SOC。电芯型号、温度、负载、电流和内阻都会影响端电压;若需要精确电量,应增加 MAX17048、BQ27441 等电量计芯片。

6. 分压按需开启,保留 ADC 诊断能力 ​

新增 KBD_VBAT_DIVIDER_ALWAYS_ON。早期实机排查阶段曾设为 1,让 PA15 持续使能分压,以便用万用表直接测量 VBAT_AD 和 PA14;正式低功耗配置现已改为 0,只在电池采样前开启分压,采样完成后关闭。

这里关闭的只是外部电池分压使能,不是完全关闭 CH592F 的 ADC 模拟电源域。ADC 模拟域仍保持开启,因此固件的 ADC 原始值、换算电压和 CHRG 原始状态诊断继续可用;维修时也可观察 PA15 在采样周期内的动作。这样避免分压电阻带来的持续耗电,同时保留判断主控是否正常运行所需的软件诊断能力。

7. 扩展 HID 诊断响应 ​

SYS_STATUS 响应由 6 字节扩展为 9 字节:

  • 新增 ADC 原始值低字节和高字节。
  • 新增 CHRG 引脚原始电平。

BATTERY 响应由 5 字节扩展为 8 字节,增加相同诊断字段。

Studio 根据响应长度判断扩展字段是否存在,因此仍兼容旧版 SYS_STATUS LEN=6 和 BATTERY LEN=5 响应。

8. 修正 Studio 的 BLE 状态文案 ​

固件连接状态枚举为:

text
0 = 未连接
1 = 广播中
2 = 已连接
3 = 挂起

原 Studio 调试终端错误地使用 data[2] === 1 判断“已连接”,因此真正返回状态 2 时反而显示“BLE 未连接”。

当前版本改为完整枚举映射。该问题只影响调试终端文案,不影响 BLE HID 报告发送;设备能够正常无线打字也说明固件 BLE 链路处于连接状态。

9. Studio 类型、编解码与测试 ​

  • BatteryInfo 和 DeviceStatus 增加可选的 adcRaw、chargePinRaw 字段。
  • CH592 编解码器按响应长度解析扩展字段。
  • 调试终端显示 ADC 与 CHRG 原始值。
  • 增加旧响应兼容测试。
  • 增加 connectionState=2 显示“BLE 已连接”的回归测试。
  • 增加 connectionState=1 显示“BLE 广播中”的回归测试。

修改文件 ​

文件改动
firmware/CH592F/hal/include/kbd_config.h启用 CHRG 检测,定义 ADC 参考值、分压比和常开诊断配置
firmware/CH592F/hal/include/kbd_battery.h更新算法说明,增加 ADC 与 CHRG 原始值接口
firmware/CH592F/hal/src/kbd_battery.c修复共享 ADC,重写采样、滤波和电量估算
firmware/CH592F/keyboard/src/kbd_command.c扩展 SYS_STATUS 与 BATTERY 响应
tools/studio/src/services/hid/common/types.ts扩展电池诊断类型
tools/studio/src/services/hid/devices/ch592/codec.ts兼容解析新旧响应
tools/studio/src/types/protocol.ts扩展系统状态类型
tools/studio/src/utils/protocolParser.ts显示原始值并修正 BLE 状态映射
tools/studio/src/utils/protocolParser.test.ts增加诊断字段、旧协议和 BLE 状态回归测试
docs/wireless/hid.md更新协议长度、字段定义、状态枚举和电量算法说明
docs/wireless/adc-fix.md本次修改的完整设计与验证记录

验证结果 ​

Studio ​

text
Test Files  5 passed
Tests       70 passed

TypeScript 类型检查和 Vite 生产构建通过。

五键固件 ​

使用以下配置完成完整构建:

text
keyboard: 5KEY
profile: release
firmware: 3.1.40

资源占用:

text
FLASH  182884 B / 216 KB  82.68%
RAM     24396 B / 26 KB   91.63%

生成并核对了在线更新用 CH592F-5KEY-3.1.40-app.bin 和首次烧录用 CH592F-5KEY-3.1.40-full.hex。

实机验证要点 ​

刷入 adc_fix 后,在 Studio 调试终端持续读取 SYS_STATUS 和 BATTERY:

  1. BLE 已配对并能打字时,应显示“BLE 已连接”。
  2. 普通充电阶段 CHRG原始值 应以 0 为主,稳定状态应显示“充电中”。
  3. TP4054 终止主充电后,CHRG原始值 应以 1 为主;满电维护阶段允许出现短暂的 0,稳定状态仍显示“未充电”。
  4. ADC 原始值应保持连续,不应再次出现约 3990 突然跳到约 1620 的状态覆盖现象。
  5. 约 4.11V 且正在充电时,百分比应在约 93% 附近,而不是停留在 60% 附近。
  6. 4.16V 以上完成连续确认后应显示 100%;CHRG 短暂补充充电脉冲不应再次切换 RGB 或稳定充电状态。
  7. 将 Studio 电压与电池两端万用表读数对照;由于 1.05V 是典型参考值,仍应在多块板上确认批次误差。

已知限制 ​

  • 电量是电压曲线估算,不是库仑计结果。
  • CHRG 高电平不能区分未接入 VBUS 与充电完成。
  • 当前 KBD_VBAT_DIVIDER_ALWAYS_ON=0 只在采样时提供有效分压点;若维修构建临时改为 1,可持续测量分压点,但会增加待机功耗。
  • ADC 参考使用 VINTA=1.05V 典型值,若量产板存在一致性偏差,应增加板级校准系数或使用电量计。