ISRW1 Internal Short Detection - Port Summary
移植完成日期
2025年
移植概述
将STM32F407主机端的ISRW1电池内部短路检测算法移植到Newton电量计固件中。
其他项目移植指南
概述
ISRW1模块采用分层设计,核心算法与平台无关,仅需实现集成层接口即可移植到其他项目。
移植架构图
1 | ┌─────────────────────────────────────────┐ |
步骤1: 复制核心文件 (无需修改)
以下文件可以直接复制到目标项目,无需修改:
1 | 源文件 → 目标位置 |
这些文件包含:
- ✅ ISRW1核心检测算法
- ✅ 中值滤波 + 卡尔曼滤波
- ✅ IR表和OCV查找表
- ✅ 状态机逻辑
步骤2: 创建集成层 (需要实现)
创建平台相关的集成层文件:
2.1 创建文件
1 | [your_src]/isrw1_integration.h |
2.2 必须实现的接口函数
在 isrw1_integration.c 中实现以下接口:
接口1: 获取电池参数
1 | // 获取电池电压 (mV) |
接口2: 系统时间获取
1 | // 获取系统运行时间 (秒) |
接口3: 调试输出 (可选)
1 | // 调试打印函数 |
2.3 集成层API (对外接口)
在 isrw1_integration.h 中声明,在 .c 中实现:
1 | // 初始化ISRW1模块 |
步骤3: 修改主程序
在主程序中集成ISRW1:
3.1 添加头文件
1 |
3.2 初始化阶段
1 | void main_init(void) |
3.3 定期调用 (建议1秒)
1 | void main_loop(void) // 或定时器中断 |
步骤4: 更新电池特性表 (⚠️ 重要)
4.1 OCV表更新 (必须)
⚠️ 警告: g_isrw1_ocv_table 必须根据实际电池型号进行建模更新!
当前表格只是示例数据,必须替换为实际电池的 OCV-SOC 曲线:
1 | // isrw1_tables.c |
如何获取 OCV 数据:
- 电池厂商提供: 向电池供应商索要 OCV-SOC 曲线数据表
- 实测建模:
- 让电池静置 2-4 小时达到平衡态
- 从 100% 放电到 0%,每 5% 测量一次开路电压
- 记录电压-容量对应关系
- 电化学建模: 使用电池模型软件 (如 COMSOL, MATLAB) 进行仿真
OCV 表要求:
- 至少 10 个数据点,建议 50-100 个点
- 覆盖完整的 SOC 范围 (0%-100%)
- 电压单位: mV
- 容量单位: 0.01% (10000 = 100%)
- 必须单调递增
4.2 IR表更新 (必须)
⚠️ 警告: g_isrw1_ir_table 也需要根据实际电池更新!
1 | // isrw1_tables.c |
如何获取 IR 数据:
- 电池厂商提供: 索要 DCIR (直流内阻) vs 温度曲线
- 实测方法:
- 使用内阻测试仪在不同温度下测量
- 或使用脉冲电流法: IR = ΔV / ΔI
- 典型值参考:
- 18650锂电池: 20-80 mΩ
- 软包电池: 10-50 mΩ
- 低温时内阻增加 2-3 倍
IR 表要求:
- 至少覆盖工作温度范围 (-20°C 到 60°C)
- 温度单位: 0.1°C (-100 = -10.0°C)
- 内阻单位: mΩ (毫欧)
- 温度必须单调递增
4.3 表格验证工具
建议创建简单的验证脚本:
1 | # verify_tables.py |
步骤5: 编译配置
5.1 添加源文件到编译
将以下文件加入项目编译:
- ✅
isrw1_detect.c - ✅
isrw1_filter.c - ✅
isrw1_tables.c⚠️ 更新后的表格文件 - ✅
isrw1_integration.c
5.2 添加头文件路径
确保编译器能找到头文件:
1 | -I[your_src]/ # 包含ISRW1相关头文件的目录 |
5.3 可选配置宏
在 isrw1_detect.h 中可调整:
1 |
步骤6: 验证测试
5.1 编译验证
1 | # 编译项目,确保无错误和警告 |
5.2 功能验证
- 初始化成功,返回0
- 参数获取函数返回合理值
- 每秒调用更新函数,无异常
- 调试输出正常 (如果启用)
5.3 检测验证
- 静置60分钟后触发检测
- 充电/放电时状态切换正常
- 泄漏电流计算结果合理
- 报警阈值触发正常
移植检查清单
✅ 文件复制
-
isrw1_detect.h -
isrw1_detect.c -
isrw1_filter.h -
isrw1_filter.c -
isrw1_tables.c(复制后需更新表格数据)
✅ 电池特性表更新 ⚠️
- 获取实际电池的 OCV-SOC 曲线数据
- 更新
g_isrw1_ocv_table(至少10个点,建议50-100点) - 获取实际电池的 DCIR-温度曲线数据
- 更新
g_isrw1_ir_table(覆盖工作温度范围) - 验证表格数据单调性
✅ 接口实现
-
get_battery_voltage()- 电压读取 -
get_battery_current()- 电流读取 -
get_battery_temperature()- 温度读取 -
get_rsoc()- SOC读取 -
get_fcc()- FCC读取 -
get_system_time()- 系统时间 -
debug_print()- 调试输出 (可选)
✅ 集成层API
-
isrw1_integration_init() -
isrw1_integration_update() -
isrw1_integration_reset() -
isrw1_integration_get_leak_current() -
isrw1_integration_get_resistance() -
isrw1_integration_is_alert()
✅ 主程序修改
- 包含
isrw1_integration.h - 初始化阶段调用
isrw1_integration_init() - 定期调用
isrw1_integration_update()
✅ 编译配置
- 添加源文件到编译
- 添加头文件路径
- 编译无错误和警告
常见平台示例
STM32 (HAL库)
1 | static uint32_t get_system_time(void) |
FreeRTOS
1 | static uint32_t get_system_time(void) |
Arduino
1 | static uint32_t get_system_time(void) |
ESP32
1 | static uint32_t get_system_time(void) |
关键注意事项
⚠️ 必须更新电池特性表 (最重要!)
ISRW1 算法的检测精度完全依赖于准确的 OCV 和 IR 表!
| 表格 | 必须性 | 影响 |
|---|---|---|
| OCV表 | 必须更新 | 使用错误的OCV表会导致检测完全失效 |
| IR表 | 必须更新 | 影响内阻计算精度,建议同时更新 |
获取方法:
- 向电池供应商索要电池规格书中的 OCV-SOC 曲线和 DCIR 数据
- 使用电池测试设备实测(静置法测 OCV,脉冲法测 IR)
- 参考同型号电池的已有数据(精度较低,不推荐)
不更新表格的后果:
- ❌ 检测到的泄漏电流值不准确
- ❌ 误报警或漏报警
- ❌ 算法失去意义
⚠️ 数据单位必须正确
| 参数 | 单位 | 说明 |
|---|---|---|
| 电压 | mV | 如ADC返回V,需乘1000 |
| 电流 | mA | 充电为正,放电为负 |
| 温度 | 0.1°C | 25.6°C = 256 |
| SOC | 0.01% | 50.00% = 5000 |
| FCC | mAh | 直接返回 |
| OCV | mV | 表格中的开路电压 |
| IR | mΩ | 表格中的内阻(毫欧) |
⚠️ 更新频率要求
- 建议每秒调用一次
isrw1_integration_update() - 检测间隔默认60分钟,可配置
- 更新频率过低会影响检测精度
⚠️ 检测条件
只有同时满足以下条件才会触发检测:
- ✅ 达到检测间隔 (默认60分钟)
- ✅ 电流变化 < 50mA
- ✅ 温度变化 < 10°C (0.1°C单位 = 100)
- ✅ 当前电流 < 10mA (接近静置)
参考实现
可参考本项目中的Newton固件实现:
user/isrw1_integration.c- Newton平台集成层实现user/main.c- 主程序集成示例
Newton固件移植文件清单
新增文件
- user/isrw1_detect.h - ISRW1核心算法头文件
- user/isrw1_detect.c - ISRW1核心算法实现
- user/isrw1_tables.c - IR表和OCV表
- user/isrw1_filter.h - 滤波器头文件
- user/isrw1_filter.c - 中值滤波(必需) + 卡尔曼滤波(可选)
- user/isrw1_integration.h - Newton固件集成层头文件
- user/isrw1_integration.c - Newton固件集成层实现
- ISRW1_PORT_SUMMARY.md - 本文档
修改文件
- user/main.c
- 添加头文件:
#include "isrw1_integration.h" - 添加初始化:
isrw1_integration_init()inmain_init() - 添加更新调用:
isrw1_integration_update()aftergg_sync_result()
- 添加头文件:
关键差异处理
1. 参数获取方式
源项目: 通过I2C从SD77428电量计芯片读取
1
2
3sd77428_get_battery_voltage()
sd77428_get_battry_current()
sd77428_get_ggmem()目标项目: 直接从Newton固件内部获取
1
2
3
4
5sbsif_get_data(SBS09_BATTVOLT) // 电压
sbsif_get_data(SBS0A_BATTCURR) // 电流
sbsif_get_data(SBS60_ITDK) // 温度(0.1°C)
get_ggmem_ptr(0)[1] // FCC from GGMEM0[4-7]
get_ggmem_ptr(1)[0] // rsoc_now (0.01%) from GGMEM1[0-3]
2. 时间管理
- 源项目:
HAL_GetTick()(STM32 HAL库) - 目标项目:
systime_get_total_time()(Newton系统时间)
3. 打印函数
- 源项目:
MCU_PRINTLN() - 目标项目:
dbg_print()
4. 数据单位
- 电压: mV (一致)
- 电流: mA (一致)
- 温度: 0.1°C (一致)
- SOC: 0.01% (rsoc_now from GGMEM,不是百分比)
- FCC: mAh (一致)
功能特性
核心算法
- 检测间隔: 60分钟 (可配置
ISRW1_DETECTION_INTERVAL) - 更新频率: 每秒调用一次 (与fg_update周期一致)
- 检测原理: 比较基于电压的容量变化和基于库仑计数的容量变化
- 报警阈值: 100mA 泄漏电流 (可配置
ISRW1_LEAK_ALERT_CURRENT)
滤波处理
中值滤波 (必需)
- 窗口大小: 11个样本
- 用于电阻值平滑
- 去除异常值
卡尔曼滤波 (可选,宏控制)
- 控制宏:
ISRW1_ENABLE_KALMAN_FILTER - 用于泄漏电流平滑
- 自适应参数调整
- 控制宏:
状态机
- IDLE: 静置状态 (|I| < 10mA)
- CHARGING: 充电状态 (I > 10mA)
- DISCHARGING: 放电状态 (I < -10mA)
- 状态切换时自动重置检测定时器
调用流程
1 | main_firmware() |
API接口
初始化
1 | int32_t isrw1_integration_init(void); |
更新检测
1 | int32_t isrw1_integration_update(void); |
复位检测
1 | void isrw1_integration_reset(void); |
获取结果
1 | int16_t isrw1_integration_get_leak_current(void); // 获取滤波后的泄漏电流(mA) |
配置参数
isrw1_detect.h
1 |
isrw1_filter.h
1 |
代码空间占用(估算)
| 模块 | 大小 (约) |
|---|---|
| 核心算法 (isrw1_detect.c) | ~2KB |
| 查找表 (isrw1_tables.c) | ~0.5KB |
| 中值滤波 (isrw1_filter.c) | ~1KB |
| 卡尔曼滤波 (可选) | ~1KB |
| 集成层 (isrw1_integration.c) | ~1KB |
| 总计 | ~5.5KB |
| 不含卡尔曼 | ~4.5KB |
注意事项
1. GGMEM访问
- 当前使用
get_ggmem_ptr()直接访问gg_mem数组 - 需要确认Newton固件中GGMEM的实际内存布局
- 可能需要根据实际情况调整偏移量
2. 温度单位
- 已确认SBS60_ITDK返回0.1°C单位
- 与ISRW1算法要求一致,无需转换
3. SOC单位
- 重要: GGMEM1[0-3]存储的是rsoc_now,单位为0.01%
- 不要使用SBS0D_RSOC(百分比),会导致精度损失
4. 检测条件
算法要求以下条件才会进行检测:
- 电流变化 < 50mA
- 温度变化 < 10°C (0.1°C单位即100)
- 当前电流 < 10mA (接近静置)
- 经过完整的检测间隔(60分钟)
5. Sleep模式
- 当前在Sleep模式下不调用fg_update,因此也不会调用ISRW1
- 将来需要考虑在Sleep间隔时间累积到ISRW1定时器中
测试建议
1. 编译测试
1 | # 在Keil MDK中编译项目 |
2. 功能测试
- 初始化正常
- 参数获取正确
- 检测定时器工作
- 中值滤波有效
- 卡尔曼滤波有效(如果使能)
- 报警触发正常
3. 长期测试
- 60分钟检测周期验证
- 静置状态检测
- 充电/放电状态切换
- Sleep/Wake切换
后续优化
Sleep时间累积
- 在Sleep模式下累积经过的时间
- Wake后补偿ISRW1定时器
SBS寄存器集成
- 将检测结果存储到SBS寄存器
- 方便主机端读取
参数调优
- 根据实际测试结果调整检测间隔
- 优化滤波器参数
- 调整报警阈值
日志记录
- 将检测结果记录到BlackBox
- 方便故障分析
版本历史
| 版本 | 日期 | 说明 |
|---|---|---|
| 1.0 | 2025 | 初始移植完成 |
参考文档
- STM32F407-SDK/README_analyze_isrw1.md
- STM32F407-SDK/USAGE_EXAMPLE.md
- STM32F407-SDK/QUICK_START.md