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 协议、电池算法、诊断方法、已知限制和本修改日志。 |
问题背景
五键无线版实机调试中观察到以下问题:
- 电池分压点和 PA14 电压稳定,但 ADC 会在约
2757与1620之间跳变,显示电压随之从约4.20V跳到3.32V。 - 充电时电压从约
4.06V上升到4.11V,电量却只从60%增加到62%。 - TP4054 正在充电时,Studio 不能直接看到 ADC 和 CHRG 引脚原始值,硬件与软件读数不便对照。
- 键盘已经通过 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Ω 二分之一分压,因此电池电压换算为:
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_2 | SampleFreq_3_2 |
| PGA | ADC_PGA_1_4,-12dB | ADC_PGA_0,0dB |
| 电压公式 | ADC * 4200 / 2048 | ADC * 1050 * 2 / 2048 |
| 分压比 | 隐含在经验满量程中 | 明确为 100kΩ/100kΩ = 1/2 |
| ADC 粗校准 | 限制在 +/-64 | 使用官方粗校准,异常值限制在 +/-256 |
新的公式能直接解释 ADC 原始值与万用表电压之间的关系,不再依赖板级经验满量程常量。
3. 解决 BLE 温度检测覆盖电池 ADC 配置
BLE 温度校准与电池检测共用 CH592 ADC。原版本在使能分压后立即配置 ADC,随后等待分压稳定;等待期间 BLE 回调可能切换 ADC 通道或 PGA,导致电池转换使用了错误配置。
当前版本:
- 分压稳定等待期间不保留电池 ADC 配置。
- 真正转换前保存 ADC 通道、ADC 配置、PGA 增益位和 TouchKey 配置。
- 在短暂中断保护窗口内重新配置 PA14/AIN4 并完成采样。
- 转换结束后恢复共享外设原状态。
这项修改解决了硬件分压点稳定、软件 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%。
当前版本删除计时增长逻辑,改为:
- 使用单节 LiPo 分段电压曲线估算百分比。
- 充电时先从端电压减去
40mV,减轻 TP4054 充电电流造成的电压抬升。 - 普通充电估算最高限制为
99%,高压区连续确认满足满电锁存条件后才允许显示100%。 4.16V以上连续 3 次有效采样锁定100%,4.10V以下连续 2 次才解除。- 百分比加入
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 状态文案
固件连接状态枚举为:
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
Test Files 5 passed
Tests 70 passedTypeScript 类型检查和 Vite 生产构建通过。
五键固件
使用以下配置完成完整构建:
keyboard: 5KEY
profile: release
firmware: 3.1.40资源占用:
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:
- BLE 已配对并能打字时,应显示“BLE 已连接”。
- 普通充电阶段
CHRG原始值应以0为主,稳定状态应显示“充电中”。 - TP4054 终止主充电后,
CHRG原始值应以1为主;满电维护阶段允许出现短暂的0,稳定状态仍显示“未充电”。 - ADC 原始值应保持连续,不应再次出现约
3990突然跳到约1620的状态覆盖现象。 - 约
4.11V且正在充电时,百分比应在约93%附近,而不是停留在60%附近。 4.16V以上完成连续确认后应显示100%;CHRG 短暂补充充电脉冲不应再次切换 RGB 或稳定充电状态。- 将 Studio 电压与电池两端万用表读数对照;由于
1.05V是典型参考值,仍应在多块板上确认批次误差。
已知限制
- 电量是电压曲线估算,不是库仑计结果。
- CHRG 高电平不能区分未接入 VBUS 与充电完成。
- 当前
KBD_VBAT_DIVIDER_ALWAYS_ON=0只在采样时提供有效分压点;若维修构建临时改为1,可持续测量分压点,但会增加待机功耗。 - ADC 参考使用
VINTA=1.05V典型值,若量产板存在一致性偏差,应增加板级校准系数或使用电量计。