707电池曲线
📎 原始文档:https://www.kdocs.cn/l/caUuGxtDG0SL 707电池曲线
文件下载:battery_level.c
- 前言 由于芯片未带电量管理模块,芯片能获取到的电池信息只有电池电压。所以本电池曲线,只是基于芯片获取到的电池两端电压,然后通过一些算法来预测放电情况。只能做个大概的预测,仅供参考。
💡本文主要介绍两种方法:安时积分法、开路电压法。
2.安时积分法
2.1 原理
该算法的主要原理是欧姆定律,即测出电池两端电压,代码中固定电池内阻,就算出了通过电池端的电流,充电的时候即为充电电流,放电的时候即为放电电流,然后电池的容量是已知的,通过计算电流的增加和减少就可以知道电池的电量是多少了。
但是实际情况中,电池内阻会随着温度和环境以及使用时长变化,以及电池电压也会随着负载的增多被拉低,但目前是没有什么反馈机制来做处理的,所以代码中引入了最大充电电流和最大放电电流的概念,来限制计算出来的异常放电情况。
⚠️该方法暂无法做到一套电池曲线兼容所有电池,也无法预测电池使用久了所带来的衰减导致的不准。
2.2 流程图

2.3参数含义
#define BATTERY_CHARGE_K 0.6 //充电电流系数。需要测量实际电流大小与打印值的差异
#define BATTERY_CAPACITY 160.0 // 电池总容量,单位mAh
#define BATTERY_RESISTOR 0.36 //电池内阻,单位Ω
#define VBAT_UPDATE_SEC 8 //刷新间隔
#define BATTERY_CHANGE_SAVE 1 //电量变化超过1%时存储到vm
#define BATTERY_MAX_CHARGE_I +100.0 //最大充电电流ma
#define BATTERY_MAX_DISCHARGE_I -200.0 //最大放电电流ma
#define CHARGE_CALIBRATION_VOLTAGE 100 //充电校准电压mv
BATTERY_CHARGE_K: 充电电流系数。因为充电和放电共用一个电池曲线,充电时,电池两端电压会虚高,因此这里需要乘上个系数
BATTERY_CAPACITY: 电池总容量,单位mAh
BATTERY_RESISTOR:电池内阻,单位Ω
VBAT_UPDATE_SEC: 刷新间隔,默认8s采集一次电量
BATTERY_CHANGE_SAVE : 电量变化超过这个数值时存储到vm
BATTERY_MAX_CHARGE_I :最大充电电流,限制电压异常跳动的情况,导致的电量变化异常
BATTERY_MAX_DISCHARGE_I : 最大放电电流,限制电压异常跳动的情况,导致的电量变化异常
CHARGE_CALIBRATION_VOLTAGE :充电校准电压mv,引入该值是因为充电和放电共用一个电池曲线,充电时,电池两端电压会虚高,所以会比较快速达到100%,但实际上拔下充电后,电压下调,实际并未充满,会造成100%到90%耗电非常快的情况,因此做了一个90%电以上的充电电压校准处理,让其显示更加准确。
2.4 代码流程
1.vbat_calculate_loop
代码逻辑主要在vbat_calculate_loop这个函数之中,主要逻辑为:
- 获取vbat两端电压
- 传入vbat_predicted_current接口,得出电压差,除以内阻,估算电流
- 判断估算的电流是否异常
- 通过该公式 current_soc += (float)I * VBAT_UPDATE_SEC / 3600 / BATTERY_CAPACITY计算消耗或增加的电流
- 判断计算后的百分比是否异常
- 写入vm
2.5 ⭐参数调试方法
⭐容量、内阻如实填写,然后电池曲线,电压和百分比做好对应,两端的百分比最好密些。0%对应的电压要大于关机电压,不然会出现不到3%以下就关机,100%的电压要小于满电电压,不然会很难到达100%。
最大充放电电流理论上和亮屏时的功耗值相同,但会有些电池是虚标,或者内阻会变,会影响这个数值。先给一个值,然后从100到关机,如果30-40就关机了,说明限的太小了,要加大最大电流。同理,如果到1%很久了都没关,就减小。
⚠️这些参数是有一定物理意义的,但是实际情况下,会有出入,所以得实际调试,才能调出最佳的电池充放曲线。
3.开路电压法
3.1 原理
这种方法是传统方法,原理就是读取vbat两端电压,通过这个电压值去匹配电池曲线的数组,得出百分比。但是实际情况中,电池两端电压会有抖动,比如亮灭屏的时候会有电压变化,导致不准。
3.2 流程图

3.3 代码流程
在vbat_check中获取vbat两端电压,算出百分比,此处进行更新。
4. 公共代码流程
4.1 电池曲线初始化
本文提供两种电池曲线设置方式,1种是707可视化sdk工具配置,一种是代码端配置。
可视化工具配置 用这种方式,要将这个宏BATTERY_DATA_CURVE_BY_CODE置0,工具配置好后,代码中会在vbat_check_init函数里面通过读取vm的值来为代码中的电池曲线赋值。


代码中配置 用这种方式,要将这个宏BATTERY_DATA_CURVE_BY_CODE置1,然后按照下面的方式设置好电池曲线的电压和电量对应关系
struct battery_data_curve{
u8 reserved;
u16 voltage;
u8 percent;
};
const u8 battery_data_curve[NEW_NUM_POINTS*4]=
{
0x03 , 0xf4, 0x0c , 0x00 ,// 0% - 3316mv
0x03 , 0x97, 0x0d , 0x05 ,// 5% - 3479mv
0x03 , 0xac, 0x0d , 0x0A ,// 10% - 3500mv
0x03 , 0xbb, 0x0d , 0x10 ,// 16% - 3515mv
0x03 , 0xca, 0x0d , 0x15 ,// 21% - 3530mv
0x03 , 0xdb, 0x0d , 0x1a ,// 26% - 3547mv
0x03 , 0x04, 0x0e , 0x1f ,// 31% - 3588mv
0x03 , 0x26, 0x0e , 0x25 ,// 37% - 3622mv
0x03 , 0x50, 0x0e , 0x2a ,// 42% - 3664mv
0x03 , 0x83, 0x0e , 0x2f ,// 47% - 3715mv
0x03 , 0xb1, 0x0e , 0x34 ,// 52% - 3761mv
0x03 , 0xd5, 0x0e , 0x3a ,// 58% - 3797mv
0x03 , 0xec, 0x0e , 0x3f ,// 63% - 3820mv
0x03 , 0x16, 0x0f , 0x46 ,// 70% - 3862mv
0x03 , 0x33, 0x0f , 0x4b ,// 75% - 3891mv
0x03 , 0x5a, 0x0f , 0x50 ,// 80% - 3930mv
0x03 , 0x7f, 0x0f , 0x55 ,// 85% - 3967mv
0x03 , 0xa0, 0x0f , 0x5a ,// 90% - 4000mv
0x03 , 0xea, 0x0f , 0x5f ,// 95% - 4074mv
0x03 , 0x0b, 0x10 , 0x64 ,// 100% - 4107mv
};
4.2 判断是否需要重新校准电量
目前触发校准电压的方式有3种:
- 获取的vm值异常 ;
- 电池重新上下电 ;
3.距离上次关机,超过了24小时
客户如果想自己增加判断条件,可以自行在bat_info_need_recheck函数里面添加条件,return true即可。如果不校准电压,就会拿vm存的电压来显示。

4.3 定时器检测vbat两端电压
sdk流程会开启一个定时器,vbat_check 轮询检测vbat 的电压,做低电检测。