esp-iot-solution 中的 BQ27220 电量计驱动:从 I2C 接线到 CEDV 参数配置与采样数据采集
2026/9/19 2:21:48 网站建设 项目流程

esp-iot-solution 中的 BQ27220 电量计驱动:从 I2C 接线到 CEDV 参数配置与采样数据采集

【免费下载链接】esp-iot-solutionEspressif IoT Library. IoT Device Drivers, Documentations and Solutions.项目地址: https://gitcode.com/GitHub_Trending/es/esp-iot-solution

本指南以 components/sensors/battery_fuel_gauge/bq27220/README.md 为核心,系统讲解 ESP-IDF 生态下 BQ27220 单节锂离子电池电量计(Fuel Gauge)驱动组件的使用方法:包括 I2C 总线初始化、CEDV 电量计参数表与 Gauging 配置位的含义、驱动初始化时自动烧写电池参数的完整流程,以及配套sample-data-app工具如何以 CSV 格式采集放电数据、配合 Gauging Parameter Calculator 标定电池模型。读完本文,你将能够在 ESP32 等乐鑫芯片上快速接入 BQ27220,读取电压、电流、剩余容量、SoC、SoH 等关键指标,并为自己的电芯生成一套可用的 CEDV 参数。

组件概览:BQ27220 能做什么

BQ27220 是 TI 出品的单节锂离子电池电量计 IC,能够提供精确的电池状态监测,包括:

  • 荷电状态(State of Charge,SoC)
  • 剩余容量(Remaining Capacity,mAh)
  • 健康状态(State of Health,SoH)
  • 电压、电流、温度、平均功率、循环次数、预计剩余/充满时间等一系列关键参数

在 esp-iot-solution 中,该组件通过 I2C 接口与主机控制器通信,提供了完整的驱动实现。组件目录结构如下:

components/sensors/battery_fuel_gauge/bq27220/ ├── bq27220.c / bq27220.h # 驱动核心实现与公共 API ├── priv_include/ │ ├── bq27220_reg.h # 标准命令、Control() 子命令、解锁密钥定义 │ └── bq27220_data_memory.h # 数据存储器(Data Memory)地址映射表 ├── test_apps/ # Unity 测试工程 └── tools/sample-data-app/ # 实时采样数据采集工具

其中 bq27220.h 是唯一需要用户包含的头文件,bq27220_reg.h 与 bq27220_data_memory.h 为私有头文件,封装了芯片寄存器与数据存储器细节。

除基础功能外,组件还附带了一个工具 sample-data-app,可以实时监测电池状态,并以 CSV 格式打印数据,供 Gauging Parameter Calculator(GPCCEDV)离线生成电芯的 CEDV 参数。

快速开始:驱动使用示例

组件的使用流程非常简洁:先创建 I2C 总线,再定义 CEDV 参数与 Gauging 配置,最后调用bq27220_create()完成设备初始化。下面是在 400 kHz I2C 主模式下的完整示例(与 README.md 及 test_apps/main/bq27220_test.c 中的用法一致):

#define I2C_MASTER_SCL_IO GPIO_NUM_1 /*!< gpio number for I2C master clock */ #define I2C_MASTER_SDA_IO GPIO_NUM_2 /*!< gpio number for I2C master data */ // Default Gauging Parameter static const parameter_cedv_t default_cedv = { .full_charge_cap = 650, .design_cap = 650, .reserve_cap = 0, .near_full = 200, .self_discharge_rate = 20, .EDV0 = 3490, .EDV1 = 3511, .EDV2 = 3535, .EMF = 3670, .C0 = 115, .R0 = 968, .T0 = 4547, .R1 = 4764, .TC = 11, .C1 = 0, .DOD0 = 4147, .DOD10 = 4002, .DOD20 = 3969, .DOD30 = 3938, .DOD40 = 3880, .DOD50 = 3824, .DOD60 = 3794, .DOD70 = 3753, .DOD80 = 3677, .DOD90 = 3574, .DOD100 = 3490, }; // Default Gauging Config static const gauging_config_t default_config = { .CCT = 1, .CSYNC = 0, .EDV_CMP = 0, .SC = 1, .FIXED_EDV0 = 0, .FCC_LIM = 1, .FC_FOR_VDQ = 1, .IGNORE_SD = 1, .SME0 = 0, }; static i2c_bus_handle_t i2c_bus = NULL; static bq27220_handle_t bq27220 = NULL; i2c_config_t conf = { .mode = I2C_MODE_MASTER, .sda_io_num = I2C_MASTER_SDA_IO, .sda_pullup_en = GPIO_PULLUP_ENABLE, .scl_io_num = I2C_MASTER_SCL_IO, .scl_pullup_en = GPIO_PULLUP_ENABLE, .master.clk_speed = 400 * 1000, }; i2c_bus = i2c_bus_create(I2C_NUM_0, &conf); bq27220_config_t bq27220_cfg = { .i2c_bus = i2c_bus, .cfg = &default_config, .cedv = &default_cedv, }; bq27220 = bq27220_create(&bq27220_cfg);

几点关键说明:

  • I2C 地址:驱动在 bq27220.c 中固定使用设备地址0x55,总线创建后无需额外指定。
  • 总线依赖:组件依赖espressif/i2c_bus(版本1.4.*),因此必须先用i2c_bus_create()创建总线句柄再传入驱动,详见 idf_component.yml。
  • 硬件接线:I2C 的 SCL/SDA 需配置上拉(GPIO_PULLUP_ENABLE),示例默认使用 GPIO1(SCL)与 GPIO2(SDA),可按实际板卡修改宏定义。

深入理解 CEDV 参数表

parameter_cedv_t(定义于 bq27220.h)是 CEDV(Compensated End-of-Discharge-Voltage,补偿型放电终止电压)参数集,这些值会被写入芯片 RAM,用于针对特定电芯化学特性配置电量计。各字段含义如下:

字段含义
full_charge_cap已学习的满充容量(mAh),即实际可用容量
design_cap设计容量(mAh)
reserve_cap保留容量(mAh)
near_full接近充满阈值(mAh)
self_discharge_rate自放电率索引(0~255),自放电百分比/天 = 值 × 0.0025%
EDV00% SoC 时的放电终止电压(mV)
EDV13% SoC 时的放电终止电压(mV)
EDV2电池低电量百分比对应的放电终止电压(mV)
EMF无负载电芯电压,高于计算出的最高电芯 EDV 阈值
C0无负载、容量相关的 EDV 调整因子
R0一阶倍率依赖因子,用于补偿电池阻抗
T0电池阻抗随温度变化的调整量
R1电池阻抗随容量变化的调整量
TC冷态(T < 23°C)阻抗变化的调整量
C1EDV0 处期望保留的电池容量
DOD0 ~ DOD100放电深度(Depth-of-Discharge)0%~100% 对应的电压表(mV)

从源码结构看,这份示例参数对应一颗 650 mAh 的电芯(design_cap = 650),DOD 电压表从满电的 4147 mV 平滑下降到放空的 3490 mV,与 EDV0 一致。实际项目中的电芯参数应通过 TI 的 Gauging Parameter Calculator 工具(见下文)生成,不要直接套用示例值。

Gauging Config 配置位

gauging_config_t(bq27220.h)是一个 16 位位域联合体,对应数据存储器中 Gauging Configuration 寄存器(地址0x929B,见 bq27220_data_memory.h)。各位的语义:

含义
CCT0 = 使用 DesignCapacity() 的百分比计算 CC(默认);1 = 使用 FullChargeCapacity() 的百分比
CSYNC在有效充电终止时将 RemainingCapacity() 与 FullChargeCapacity() 同步
EDV_CMPEDV 补偿使能
SC平滑引擎(Smoothing Engine)使能
FIXED_EDV0固定 EDV0 使能
FCC_LIM满充容量限制
FC_FOR_VDQ使用满充电压用于 VDQ
IGNORE_SD忽略自放电
SME0平滑引擎模式选择

默认配置中启用了CCT(基于满充容量计算)、SC(平滑)、FCC_LIMFC_FOR_VDQIGNORE_SD,适合大多数消费类应用。

驱动初始化流程:bq27220_create 内部做了什么

bq27220_create()(bq27220.c)并非简单的句柄分配,而是一次完整的设备验证与电池参数编程流程:

  1. 参数校验:检查configi2c_buscedvcfg均非空,分配驱动数据结构并在 I2C 总线上创建0x55地址的设备句柄。
  2. 设备识别:通过Control()子命令CONTROL_DEVICE_NUMBER(0x0001)请求设备号,再从 MAC scratch 空间(0x40)读回,必须等于BQ27220_DEVICE_ID(0x0220),否则初始化失败——这是防止 I2C 接错器件的关键保护。
  3. 版本读取:读取固件版本(CONTROL_FW_VERSION)与硬件版本(CONTROL_HW_VERSION)并打印日志,例如启动日志中的Firmware Version 2002/Hardware Version 0004
  4. 解除密封:调用bq27220_unseal(),通过两个解锁密钥UNSEALKEY1 = 0x0414UNSEALKEY2 = 0x3672(bq27220_reg.h)进入未密封状态以访问配置数据。
  5. 参数比对与烧写:先读取芯片当前的设计容量、EMF、T0、DOD20 与传入 CEDV 参数比对;若完全一致则跳过烧写并打印Skip battery profile update。否则进入 Config Update 模式(CONTROL_ENTER_CFG_UPDATE,0x0090),通过Select Subclass(0x3E)+MAC Data(0x40)+MAC Data Sum(0x60)逐项写入 Gauging Configuration、满充容量、设计容量、近满阈值、自放电率、保留容量、EDV0/1/2、EMF、C0/R0/T0/R1、TC/C1 以及 DOD0~DOD100 电压表,随后用CONTROL_EXIT_CFG_UPDATE_REINIT(0x0091)退出并复位。
  6. 校验与密封:回读设计容量确认写入成功(日志Battery profile update success),最后执行bq27220_seal()防止配置数据被意外篡改。

整个流程涉及数据存储器写操作的校验和机制:bq27220_set_parameter_u16()会先发送 [地址低字节、地址高字节、值高字节、值低字节] 四个字节,再发送对这四个字节求反的校验和以及固定长度 6(见 bq27220.c)。

值得注意:bq27220_create()内部会把TCC1打包进同一个 16 位字((TC << 8) | C1)写入0x92B1,对应数据存储器中 TC(0x92B1)与 C1(0x92B2)相邻的布局。

公共 API 一览:读取电池关键指标

bq27220.h 提供了丰富的只读查询接口,全部通过标准命令(Standard Commands)直接读取,底层实现见 bq27220.c:

API返回内容
bq27220_get_voltage()电池电压(mV)
bq27220_get_current()瞬时电流(mA),充电为正、放电为负
bq27220_get_avgcurrent()平均电流(mA)
bq27220_get_temperature()温度(0.1°K,转换为摄氏度需/10 - 273
bq27220_get_remaining_capacity()剩余容量(mAh)
bq27220_get_full_charge_capacity()补偿后的满充容量(mAh)
bq27220_get_design_capacity()设计容量(mAh)
bq27220_get_state_of_charge()荷电状态 SoC(0~100%)
bq27220_get_state_of_health()健康状态 SoH(0~100%,满充容量/设计容量之比)
bq27220_get_cycle_count()充放电循环次数
bq27220_get_charge_voltage()/bq27220_get_charge_current()充电电压(mV)/ 充电电流(mA)
bq27220_get_average_power()平均功率(mW),充电为正、放电为负
bq27220_get_time_to_empty()/bq27220_get_time_to_full()预计放空/充满时间(分钟)
bq27220_get_maxload_current()/bq27220_get_standby_current()最大负载电流 / 待机电流(mA)
bq27220_get_battery_status()电池状态位域(充放电状态、FC/FD、OCV 标志等)
bq27220_get_operation_status()运行状态位域(SEC 安全等级、CFGUPDATE、INITCOMP 等)
bq27220_get_fw_version()/bq27220_get_hw_version()固件/硬件版本
bq27220_seal()/bq27220_unseal()密封/解除密封配置访问
bq27220_set_parameter_u16()/bq27220_get_parameter_u16()按数据存储器地址读写 16 位参数
bq27220_delete()释放句柄并删除 I2C 设备

其中battery_status_toperation_status_t均为位域联合体,便于直接读取如DSG(放电中)、FC(已满充)、FD(已满放)、SEC(当前安全访问等级)等状态位;两结构体均通过ESP_STATIC_ASSERT强制占用 2 字节以匹配寄存器宽度。

sample-data-app:为 GPCCEDV 采集标定数据

BQ27220 的电量计精度高度依赖 CEDV 参数与真实电芯的匹配度。组件自带的 sample-data-app 工具就是为此设计的:它从 BQ27220 读取数据,以 CSV 格式在控制台打印放电过程数据,供 TI 的 Gauging Parameter Calculator(GPCCEDV)工具使用,从而生成该电芯专属的 CEDV 参数。

菜单配置

工具参数全部通过 menuconfig 配置,定义于 Kconfig.projbuild:

配置项默认值说明
CONFIG_I2C_SCL_IO1I2C SCL 引脚
CONFIG_I2C_SDA_IO2I2C SDA 引脚
CONFIG_DISCHARGE_ENABLE_IO4放电使能 GPIO(低电平先关闭放电,初始化文件系统后再拉高开始放电)
CONFIG_END_DISCHAGE_VOLTAGE3300结束放电电压(mV),即采样记录停止的阈值

默认结束放电电压为 3.3V,可通过 menuconfig 修改。

采集逻辑

main.c 的流程是:

  1. 初始化 I2C 总线与 BQ27220(使用与上文相同的默认 CEDV 参数与 Gauging 配置);
  2. 将放电使能 IO 配置为输出并拉低,挂载 SPIFLASH 上的 FAT 文件系统(/log分区);
  3. 拉高放电使能 IO 开始放电,随后以 2 秒间隔调用bq27220_get_voltage()bq27220_get_current()bq27220_get_temperature()采集数据,温度从 0.1°K 转换为摄氏度;
  4. 当电压低于结束放电电压(默认 3300 mV)时停止记录,关闭放电并卸载文件系统。

输出格式

CSV 输出由printf直接打印到控制台,表头与数据格式如下(节选自 tools/sample-data-app/README):

I (311) bq27220_sample: Hello BQ27220 Battery Fuel Gauge! I (316) bq27220_sample: Discharge enable IO: 4 I (321) bq27220_sample: I2C master SCL IO: 1 I (325) bq27220_sample: I2C master SDA IO: 2 I (329) i2c_bus: i2c0 bus inited I (331) i2c_bus: I2C Bus V2 Config Succeed, Version: 1.1.0 I (370) bq27220: Firmware Version 2002 I (386) bq27220: Hardware Version 0004 I (452) bq27220: Design Capacity: 650, EMF: 3670, T0: 4547, DOD20: 3969 I (452) bq27220: Skip battery profile update I (453) bq27220_sample: End discharge voltage: 3300 -------- Start record -------- ElapsedTime, Voltage, Current, Temperature 0, 4078, -33, 27.8 2, 4077, -32, 27.7 4, 4077, -32, 27.7 6, 4077, -32, 27.8 8, 4077, -32, 27.7 10, 4077, -32, 27.7 12, 4077, -32, 27.7 14, 4077, -32, 27.8 16, 4076, -32, 27.8 18, 4077, -32, 27.8 20, 4076, -32, 27.7 22, 4076, -32, 27.8 24, 4076, -32, 27.8 26, 4076, -32, 27.7 ......

采集完成后,把完整的 CSV 数据交给 GPCCEDV 工具即可得到针对当前电芯的 CEDV 参数,再回填到parameter_cedv_t结构中,即可完成一次电芯标定闭环。工具的 CMake 通过EXTRA_COMPONENT_DIRS "../../../bq27220"直接复用组件源码(CMakeLists.txt),并使用 partitions.csv 划分出日志分区。

测试与验证

组件提供了基于 Unity 的测试工程 test_apps,其中 bq27220_test.c 覆盖了两类用例:

  • 基础信息查询测试bq27220 basic information query test):完成创建→读取电池状态、电压、电流、剩余/满充容量、温度、循环次数、SoC、平均功率、最大负载、预计时间等全量信息→删除的完整链路;
  • 内存泄漏检测setUp/tearDown中通过heap_caps_get_free_size()对比 8-bit 与 32-bit 堆空闲量,阈值首次为 -110 字节、之后为 0,确保 create/delete 循环无内存泄漏。

该测试同时验证了驱动的 I2C 时序、命令交互与资源回收正确性,可作为自己项目接入时的参考模板。

工程集成要点

  • 组件依赖(idf_component.yml):espressif/i2c_bus 1.4.*(public 依赖)、cmake_utilities 0.*,并要求 IDF>=4.4。若在组件管理器(Component Manager)下使用,bq27220会自动拉取这些依赖。
  • 构建配置(CMakeLists.txt):仅需driver组件作为编译依赖,priv_include目录不对外暴露。
  • 版本信息:当前版本 v0.1.1(2025-09-22),修复了 i2c_bus 依赖改为 public 导致的编译错误;v0.1.0(2025-08-12)为初始版本,提供 BQ27220 基本功能,详见 CHANGELOG.md。
  • 许可:驱动源码以 Apache-2.0 / CC0-1.0 双许可形式发布,详见各文件 SPDX 头与 license.txt。

小结

esp-iot-solution 的 BQ27220 组件以"一次 create、自动完成设备识别—解锁—参数烧写—密封"的设计,把电量计接入的门槛降到了最低:上层只需定义好 CEDV 参数与 Gauging 配置,之后即可通过一组bq27220_get_*接口轮询电池状态。配合sample-data-app工具与 GPCCEDV 的标定流程,开发者可以从零为任意一款单节锂电建立精确的电量模型。建议在正式产品中:

  1. 使用 GPCCEDV 基于实际电芯生成 CEDV 参数,替换示例中的默认值;
  2. 按产品功耗与安全要求,通过 menuconfig 调整结束放电电压等采样参数;
  3. 参考 test_apps 中的读取与泄漏检查模式,把电池信息上报纳入自己的业务循环。

【免费下载链接】esp-iot-solutionEspressif IoT Library. IoT Device Drivers, Documentations and Solutions.项目地址: https://gitcode.com/GitHub_Trending/es/esp-iot-solution

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询