电量计 -- 满充时间预估功能说明

满充时间预估功能说明

目录


功能概述

满充时间预估(Time To Full, TTF)功能用于估算电池从当前状态充满到100%SOC所需的时间。

特性

  • 支持两种计算模式(由TIME_ESTIMATION_MODE宏控制)
  • 通过SBS标准接口对外提供数据
  • 支持充电时间(TTF)和放电时间(TTE)两种预估
  • 输出单位为分钟

文件位置

文件 说明
lib/lib_fg.c 核心算法实现
flash/sbs.c SBS接口封装
lib/lib_fg.h 库函数声明

原理说明

计算模式选择

1
2
// lib/lib_fg.c 和 flash/sbs.c 必须同步配置
#define TIME_ESTIMATION_MODE 1 // 0=简单线性模式, 1=CC-CV分阶段模式
模式 描述 适用场景
Mode 0 简单线性模式:时间 = 容量/电流 快速估算
Mode 1 CC-CV分阶段模式(推荐) 精确预估,考虑充电曲线特性

Mode 1 算法原理

1. 充电阶段识别

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
┌─────────────────────────────────────────────────────────────┐
│ 充电曲线示意图 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 电压 ┌────────────────── CC阶段 ─────────────────┐ │
│ ▲ │ (恒流) │ │
│ │ │ │ │
│ │ │ 电流固定 ↑ │ │
│ │ │ 电压上升 → │ │
│ │ │ SOC: 0% → 70% │ │
│ │ └───────────────────────────────────────────── │ │
│ │ ┌────── CV阶段 ────┐ │ │
│ │ │ (恒压) │ │ │
│ │ 电流下降 ↓ │ 电压固定 │ │ │
│ │ SOC: 70% → 100% │ 电流衰减 │ │ │
│ └────────────────────────────────────┴──────────────────┘ │ │
│ │
│ ●──────────── CC2CV_SOC ──────────────────●─────────100% │
│ 0% 70% │
│ │
│ SOC分界点: TTE_CC2CV_SOC = 7000 (即70%) │
└─────────────────────────────────────────────────────────────┘

2. CC阶段时间计算

当SOC < 70%时:

1
CC阶段时间 = (CC2CV_SOC - 当前SOC) × CC典型时间 / CC2CV_SOC × (默认CC电流 / 当前电流)

3. CV阶段时间计算

当SOC ≥ 70%时:

1
CV阶段时间 = CV典型时间 × (1 - 阶段进度比例)

其中阶段进度使用二次函数计算:

1
2
3
4
5
// 总分段数 = ((1 + SHIFT) + (总阶段数 + SHIFT)) × 总阶段数 / 200
total_pieces = ((1 + 100) + (3000 + 100)) × 3000 / 200 = 46500

// 剩余分段数
remain_pieces = ((1 + SHIFT) + (当前阶段 + SHIFT)) × 当前阶段 / 200

接口定义

SBS寄存器

地址 名称 类型 说明 单位
0x13 ATTF 只读 满充时间预估 (Average Time To Full) 分钟
0x12 ATTE 只读 放空时间预估 (Average Time To Empty) 分钟

数据源寄存器

地址 名称 说明
0x0B AVGCURR 平均电流 (mA)
0x0D RSOC 相对剩余容量 (0.01%分辨率)
0x0F RC 剩余容量 (mAh)
0x18 DSNCAP 设计容量 (mAh)

外部变量

1
2
// lib/lib_fg.c - 全局变量
extern signed int fg_est_time_sec; // 预估时间,单位秒

数据流程

完整调用链

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
┌──────────────────────────────────────────────────────────────────┐
│ 主机读取流程 │
├──────────────────────────────────────────────────────────────────┤
│ │
│ 1. 主机发送I2C读取命令 [0x16, 0x13] │
│ ↓ │
│ 2. sbsif_get_data(SBS13_ATTF) │
│ ↓ │
│ 3. sbs_get_attf() [flash/sbs.c] │
│ ↓ │
│ 4. 检查TIME_ESTIMATION_MODE: │
│ ├─ Mode 1: 直接使用fg_est_time_sec (秒→分钟) │
│ └─ Mode 0: 调用sbs_time_to_full() 线性计算 │
│ ↓ │
│ 5. 返回预估时间(分钟) │
│ │
└──────────────────────────────────────────────────────────────────┘

内部计算流程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
┌──────────────────────────────────────────────────────────────────┐
│ oz8806_time_estimation() │
├──────────────────────────────────────────────────────────────────┤
│ │
│ 1. 判断充电/放电/空闲状态 │
│ ├─ 充电(AC): imode = 1 │
│ ├─ 放电: imode = -1 │
│ └─ 空闲: imode = 0 │
│ ↓ │
│ 2. 模式切换检测 │
│ └─ 状态变化时重置: fg_est_time_sec = -1 │
│ ↓ │
│ 3. 平滑平均电流计算 │
│ └─ fg_est_cavgln_curr = (前一值×(n-1) + 当前值) / n │
│ ↓ │
│ 4. 每5秒调用fg_time_estimation()重新计算 │
│ ↓ │
│ 5. 返回 fg_est_time_sec (秒) │
│ │
└──────────────────────────────────────────────────────────────────┘

fg_time_estimation() 分支逻辑

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
                          ┌─────────────────┐
│ fg_time_estimation() │
└─────────┬───────────┘

┌──────────────────────────┼──────────────────────────┐
↓ ↓ ↓
┌─────────────────┐ ┌──────────────────┐ ┌─────────────────┐
│ 电流接近0/静置 │ │ 放电模式 │ │ 充电模式 │
│ imode=0 且|电流│ │ imode<0 且|电流│ │ imode>0 且电流│
│ <30mA │ │ >70mA │ │ >70mA │
└────────┬────────┘ └─────────┬─────────┘ └────────┬────────┘
│ │ │
↓ ↓ ↓
┌─────────────────┐ ┌──────────────────┐ ┌─────────────────┐
│ SOC=100%: │ │ TTE计算: │ │ SOC<70%(CC阶段) │
│ 每秒-5秒 │ │ 容量×36/电流 │ │ (CC2CV-SOC)× │
│ │ │ │ │ CC_TIME × Idef/I
│ SOC>70%且CV状态:│ │ 例: 3000mAh │ │ + CV_TIME │
│ 快速估算 │ │ @500mA放电 │ │ │
│ │ │ = 3000×36/500 │ │ SOC≥70%(CV阶段)│
│ 其他: -1 │ │ = 216秒 ≈ 3.6分钟│ │ 二次函数计算 │
└─────────────────┘ └──────────────────┘ └─────────────────┘

关键参数

时间估算常量 (lib_fg.c)

参数 说明
TTE_CC2CV_SOC 7000 CC→CV分界点 (70%)
TTE_DEFAULT_CC_CURRENT 4000 mA 默认CC充电电流
TTE_CC_TIME_SEC 2700秒 CC阶段典型时长
TTE_CV_TIME_SEC 2000秒 CV阶段典型时长
TTE_STAGE_SHIFT 100 CV阶段二次函数偏移

电流阈值 (lib_fg.c)

参数 说明
CALC_TIME_CURRENT_TH 30 mA 静置判定阈值
DISCH_CURRENT_TH 70 mA 放电判定阈值
MW_CHG_CURR 30 mA 满充后充电电流阈值
MW_IDLE_CURR -50 mA 静置电流下限

平滑参数

参数 说明
TIMENUM 5 采样平均次数
FG_SHORT_AVG_CNTR 15 短时电流平均窗口
FG_LONG_AVG_CNTR 45 长时电流平均窗口

GPM调整参数 (flash/sbs.c Mode 0)

参数 说明
GPM_ATTFADJMUL 40 SOC>75%时的时间调整分子
GPM_ATTFADJDIV 25 SOC>75%时的时间调整分母
1
2
// Mode 0 修正公式 (SOC > 75%)
调整值 = (100 - SOC) × 40 / 25

调试方法

1. 启用调试日志

1
2
3
4
5
// lib_fg.c 中启用
#define LIB_FG_MSG 1 // 开启时间估算日志

// 日志输出示例:
// oz8806_time_estimation: imode=1, curr=1500mA, rsoc=4500, tte=3650sec

2. 寄存器读取验证

通过I2C读取关键寄存器:

1
2
3
4
5
6
7
8
# 读取预估时间
i2c_read 0x13 # ATTF - 应返回分钟数

# 读取平均电流
i2c_read 0x0B # AVGCURR - 确认充电电流

# 读取SOC
i2c_read 0x0D # RSOC - 确认当前SOC

3. 计算验证

1
2
3
4
// 手动验证计算
int expected_time = (10000 - rsoc) * TTE_CC_TIME_SEC / 10000;
expected_time = expected_time * TTE_DEFAULT_CC_CURRENT / current_mA;
expected_time = expected_time + TTE_CV_TIME_SEC;

4. 调试检查点

检查点 预期值 异常排查
充电时ATTF > 0 检查适配器状态
SOC=0时ATTF ≈ CC+CV总时间 检查DSNCAP配置
SOC=100时ATTF 0 或递减 检查充电结束判定
放电时ATTE > 0 检查放电状态

5. 常见波形观察

使用示波器或数据记录观察:

1
2
3
4
正常充电曲线示例:
SOC: 0% → 10% → 30% → 50% → 70% → 90% → 100%
TTF: 90m → 80m → 65m → 50m → 35m → 20m → 0m
└──── CC阶段 ────┘ └────── CV阶段 ────────┘

常见问题

Q1: ATTF返回值为0

可能原因:

  • 未在充电状态
  • 电流小于阈值(30mA)
  • fg_est_time_sec < 0

排查步骤:

1
2
3
4
5
6
7
8
9
10
11
12
// 检查适配器状态
if (g_adapter_status != O2_CHARGER_AC) {
printf("未连接充电器\r\n");
}

// 检查电流
if (batt_info.fCurr < 30) {
printf("充电电流太小\r\n");
}

// 检查预估变量
printf("fg_est_time_sec = %d\r\n", fg_est_time_sec);

Q2: 预估时间偏差大

可能原因:

  • 充电电流波动大
  • 温度影响
  • 电池老化

优化方法:

  1. 检查充电曲线是否符合CC-CV特性
  2. 调整TTE_CC_TIME_SECTTE_CV_TIME_SEC
  3. 检查O2_CONFIG_EOC充电截止电流配置

Q3: 模式切换时预估重置

现象:

  • 拔插充电器时预估时间变为负值

原因: 这是正常行为 - 模式切换时fg_est_time_sec被重置为-1

预期恢复时间: 约5秒后恢复正常预估

Q4: MODE 0和MODE 1结果不一致

原因: 两种模式算法不同

  • Mode 0: 简单线性 (剩余容量×60)/电流
  • Mode 1: CC-CV分阶段,考虑充电曲线特性

建议: 使用Mode 1(推荐)以获得更精确的预估


配置示例

标准配置 (Mode 1)

1
2
3
4
5
6
7
8
9
10
// lib/lib_fg.c
#define TIME_ESTIMATION_MODE 1

// CC-CV分界点: 70% SOC
#define TTE_CC2CV_SOC 7000

// 针对4000mAh电池 @ 2000mA充电
#define TTE_DEFAULT_CC_CURRENT 2000 // mA
#define TTE_CC_TIME_SEC 1890 // (7000/10000)*2700*2000/4000 ≈ 1890s
#define TTE_CV_TIME_SEC 1500 // CV阶段约25分钟

快速充电配置

1
2
3
4
// 针对快充充电器 @ 4000mA
#define TTE_DEFAULT_CC_CURRENT 4000 // mA
#define TTE_CC_TIME_SEC 2700 // 典型值
#define TTE_CV_TIME_SEC 2000 // 典型值

版本信息

版本 日期 说明
v1.0 2025-12 初始版本,支持CC-CV分阶段预估
v1.1 2026-02 优化充放电阻抗曲线参数

文档生成日期: 2026-03-25