☰
STM32F103+BQ76920锂电池BMS设计:从采样电路到量产实践
2026/10/14 16:01:09 网站建设 项目流程

简介:这是一套基于STM32F103主控与BQ76920专用电池监控芯片实现的完整锂电池管理系统(BMS)工程,面向电子信息、自动化、通信工程等专业的在校学生、毕设开发者及嵌入式初学者,解决多节锂电的电压/温度采集、均衡控制、过压欠压保护、SOC估算等核心管理需求。压缩包共1003个文件,含576个C源码(含ARM CMSIS-DSP数学库调用如arm_rfft_init_f32.c等)、265个头文件、51个汇编启动文件、28个IAR链接脚本及13个PCB光绘文件(GBR),完整覆盖原理图(KiCad)、PCB设计、固件开发与硬件调试全流程,包体大小为26.69MB。已有198人下载学习,资源经实测可稳定运行,配套详细文档说明与README指引,支持远程答疑与基础教学;用户可直接用于课程设计、毕业设计或商业项目二次开发,具备清晰模块划分与良好可扩展性。 做电池管理系统最怕什么?怕电芯电压采集不准,怕保护逻辑动作不及时,怕量产之后问题反复出现。我这套基于 STM32F103 和 BQ76920 的锂电池管理系统,从原理图到 PCB,从驱动代码到上位机协议,前后折腾了大半年,把能踩的坑基本都踩了一遍,最后整理成一套资料完整、能直接投入生产的方案。标题里没有夸张,这套东西确实可以去做商业用途——选这两个芯片就是奔着量产可靠性去的,不是那种只能在面包板上点个灯的学习板。

如果你正在做储能、电动工具、轻型电动车、便携设备电源管理,或者只是想把锂电池保护从“分立元件方案”升级到“模拟前端+MCU方案”,这篇文章会把你从选型、电路设计、PCB 布板一路带到软件实现和产测注意事项。我会把为什么选这个方案、每个关键器件怎么搭、PCB 上哪些地方绝对不能错、代码里保护逻辑怎么写、以及实际调试中碰到的问题,全部摊开来聊一遍。

1. 项目整体设计与思路拆解

1.1 这套 BMS 到底在解决什么问题

先理清一个概念:锂电池管理系统(BMS)不是简单加一块保护板就完事,它解决的是整个电池组的“安全、寿命、状态可知”三个问题。

安全方面,锂电池串联成组之后,每一节电芯的电压都必须被实时监控。过充会导致正极材料结构损坏甚至热失控,过放会导致负极析铜形成内部微短路,这些风险跟电芯数量无关,跟电压管理精度强相关。寿命方面,串联电芯之间必然存在容量和自放电率的差异,如果放任不管,容量最低的那节电芯会最先到达截止电压,整组电池的实际可用容量被它锁死,所以需要均衡电路。状态可知方面,设备端需要知道当前还剩多少电、还能用多久,这就要靠 SOC(剩余电量)估算。

这套方案的核心定位是 3~5 串锂电池组,覆盖了绝大多数小功率场景。BQ76920 负责前端的电压/电流/温度采集和硬件保护,STM32F103 作为主控负责策略逻辑、通信交互和参数管理。两层架构的好处是:模拟前端用专用芯片保证采集精度和保护响应速度,MCU 负责灵活性,两者各干各擅长的事。

1.2 为什么偏偏是 STM32F103 + BQ76920

这个组合放在今天的市场里,可能有人会觉得不够“新”,但“成熟可靠”本身就是量产选型的第一优先级。BQ76920 是 TI 电池管理产品线里的入门款模拟前端,支持 3~5 节串联锂电池,内部集成了 14 位 ADC 用于电压和温度采集,16 位 ADC 用于电流采集,还集成了二级保护、充放电 FET 驱动和被动均衡功能。这些功能如果全部用分立器件做,PCB 面积至少大三倍,保护精度和一致性还未必比得上。

STM32F103 更不用多说,Cortex-M3 内核,72MHz 主频,I2C、USART、SPI、CAN 一应俱全,资料和生态非常成熟。在 BMS 场景里,它的任务并不重:周期轮询 BQ76920 读数据、跑状态机、执行保护策略、通过串口或 CAN 上报数据,这些工作负载对它来说很轻松,反而给代码留出了充足的余量去加调试信息、做异常记录、跑自检逻辑。

也有人会问:为什么不用 BQ76930 或者 BQ76940?两个原因:成本和不必要的复杂度。BQ76930 支持 10 节,BQ76940 支持 15 节,芯片本身更贵,寄存器配置也更复杂。5 串以内的应用选 BQ76920 是最经济的,后面要扩展到 10 串,软件框架可以平移,但硬件方案就得换芯片了,这是产品初期定义规格时要想清楚的。

2. 硬件设计与 PCB 实操要点

2.1 BQ76920 外围电路:供电、采样、保护参数计算

BQ76920 的供电方式跟普通芯片不一样,它直接由电池堆顶部供电,REGIN 引脚通过一个电阻接到最高节电芯正极,内部稳压出 REGOUT(默认 3.3V)供芯片自身和外部逻辑使用。这个“直接从电池取电”的设计省掉了一路独立的电源转换,但也带来一个隐患:如果电池堆电压是 20V 左右,REGIN 到 REGOUT 之间的压差全部耗散在内部线性稳压器上,电流较大的时候芯片会发热。所以一定要按参考设计把 REGIN 的限流电阻算好,通常是 100Ω 左右,让内部稳压器工作在安全功耗范围内。

电压采样是 BQ76920 的核心功能,VC0~VC5 这 6 个引脚分别接到每节电芯的极柱上,内部通过多路开关依次接入 ADC。外部必须每节电芯加一个 100Ω 电阻和一个 100nF 电容构成 RC 滤波,这个滤波电路有两个作用:滤除高频噪声,防止 ADC 采样结果跳动;同时限制异常浪涌电流,保护芯片内部的多路开关。这里有一个新手最容易犯的错误——采样线接反或者漏接,ADC 读出来的数据会完全没有规律,甚至可能损坏芯片。

电流采样引脚是 SRP 和 SRN,两者之间接采样电阻。采样电阻的阻值决定电流检测的分辨率和量程,BQ76920 内部电流 ADC 的满量程电压大约是 ±200mV,如果采样电阻用 1mΩ,那么满量程就是 ±200A。实际工程里,电池组的持续工作电流一般在 10A~30A,建议选 1mΩ 或者 2mΩ 的合金电阻。阻值大了分辨率高,但功耗也大,30A 电流在 2mΩ 电阻上的功耗是 1.8W,电阻选型必须按这个功耗找对应封装,否则温度漂移会让你怀疑人生。

温度采样用的是芯片内部的恒流源,推荐用 10kΩ NTC 热敏电阻,一端接 BAT 引脚,另一端通过热敏电阻接地,中间抽头接到 TS1 引脚。参考设计里还有一个分压电阻网络,目的都是把温度对应的阻值变化转换成电压变化。我的经验是温度采样点不要只放一个,电池组的电芯温度一致性没有想象中那么好,至少放两个 NTC,一个靠近中间电芯,一个靠近边缘电芯。

2.2 STM32F103 最小系统与接口设计

STM32F103 最小系统本身不复杂:8MHz 晶振、复位电路、BOOT 选择、SWD 下载口、3.3V 供电。但在 BMS 产品里,MCU 的电源设计需要多考虑一步——不要直接用 BQ76920 的 REGOUT 给 MCU 供电。REGOUT 的负载能力有限,MCU 运行期间引脚翻转、通信收发都会产生电流波动,如果共用一路,模拟前端的 ADC 参考电压会跟着抖,直接影响采样精度。

推荐的做法是 BQ76920 的 REGOUT 单独给电平转换和逻辑电路供电,MCU 用独立的 LDO 供电,比如从电池电压经过宽压 DC-DC 降到 5V,再经过 LDO 降到 3.3V。这样既保证了模拟前端的电源纯净度,又能让 MCU 的功耗波动不影响采样。

对外接口方面,我保留了三种:UART 调试口、CAN 通信口、I2C 扩展口。UART 用于产测和现场调试,CAN 用于和上位机或者整车控制器通信,I2C 扩展口留给以后接外部 EEPROM 或者扩展板。实际项目里,通信隔离是个容易被忽略的点。如果电池包和控制器之间没有良好共地,地环路会导致通信异常甚至损坏芯片,保险起见,CAN 和 UART 都建议加隔离。设计时预留隔离器件的封装和隔离电源的位置,后期按需焊接。

2.3 PCB Layout 关键区域:电流采样、功率地与信号地

这块 PCB 的 Layout 质量直接决定这套 BMS 稳不稳,尤其是电流采样那一小块,无数项目在这里栽过跟头。

第一,采样电阻必须做开尔文(四线制)连接。大电流路径从采样电阻两端流过,如果 SRP 和 SRN 的走线直接从大电流路径上引出来,铜箔的寄生电阻会串进采样回路,电流读数会有固定偏差。正确做法是:从采样电阻焊盘的内侧边缘单独引两条细走线到 BQ76920 的 SRP/SRN 引脚,走线尽可能短且等长,形成独立的电压检测回路。

第二,功率地和控制地要单点连接。电池负极大电流回流路径上,任何一小段铜箔在 20A 电流下都会产生毫伏级压降,如果这个压降跑到信号地里,ADC 数据会随机跳动。我把功率地铺在底层,控制地铺在顶层,两者通过一个 0Ω 电阻在 BQ76920 附近的单点连接,这个位置同样也要靠近 SRP/SRN 采样点,保证采样回路不被功率电流污染。

第三,电池采样线进入 BQ76920 之前的 RC 滤波电路,必须靠近芯片引脚放置。100Ω 电阻和 100nF 电容的位置如果远离芯片,中间那段走线就成了天线,反而把噪声耦合进采样回路。PCB 上这 6 组 RC 滤波电路的布局要保持一致,走线长度不要相差太多,不然 6 节电芯的采样结果会带不同的相位延迟。

第四,MOS 驱动和散热。充放电 MOS 管在工作时会有持续功耗,以 Rds(on) 为 10mΩ、电流 20A 计算,单管功耗就有 4W,这个热量必须通过大面积铜箔和过孔阵导到 PCB 背面。同时,BQ76920 的 CHG 和 DSG 引脚是开漏输出,驱动高边 NMOS 时需要外部上拉到电池堆电压,这个上拉的电压必须足够高,否则 MOS 管工作在放大区会严重发热。我会在软件初始化时专门检查 FET 状态寄存器,确保驱动电压建立正常。

3. 软件架构与核心实现

3.1 整体软件框架:状态机模型

软件架构我用的是一个经典的状态机模型,外加一个轻量级前后台调度。主循环负责轮询状态机,定时器中断负责产生 1ms、10ms、100ms 的时基,驱动 ADC 采集、通信处理、保护检测这些周期任务。这种结构简单可靠,不引入 RTOS 的额外复杂度,而且整个代码量对 STM32F103 来说完全在掌控范围内。

状态机模型划分了 6 个状态:上电自检、待机、充电、放电、保护、故障。上电自检阶段,MCU 和 BQ76920 完成初始化,读取上次保存的参数,检查电池组是否满足工作条件;待机状态下系统以最低功耗运行,周期性轮询电压和温度,但不打开充放电 FET;进入充电或放电状态后,保护检测任务以高频运行;保护状态表示某个保护条件触发,系统会保存故障码并控制 FET 关断;故障状态则是不可自动恢复的硬件异常,比如 EEPROM 校验失败、模拟前端通信失败。

每个状态之间的切换条件都对应具体的事件,比如“充电过压保护”事件会把系统从充电状态切到保护状态,“恢复条件满足”事件会把系统从保护状态切回待机。这种设计的好处是逻辑可预测、问题可复现,现场出现异常时通过串口打印状态机和事件码,基本五分钟内就能定位问题。

3.2 BQ76920 驱动:I2C 通信与寄存器操作

BQ76920 的驱动是整个软件的核心底层,所有上层逻辑都依赖它提供准确的数据。I2C 通信配置为 400kHz,这是 BQ76920 支持的最高速率。地址方面要特别小心:BQ76920 的 7 位 I2C 地址是 0x08,这在 BMS 领域算是个很特殊的地址,因为 0x08 是系统保留地址之一,部分 MCU 的 I2C 外设初始化时会跳过这个地址,我一开始就因为这个原因导致通信时好时坏,后来改成软件模拟 I2C 才彻底解决。

BQ76920 的寄存器操作有几个关键流程:首先是初始化序列,把 REG0 配置为 0x00(进入配置模式),然后依次设置保护阈值寄存器、ADC 采样配置寄存器、FET 使能寄存器,最后把 REG0 切回 0x02(正常模式)并启动 ADC。整个初始化序列必须在 I2C 通信稳定后一次做完,如果中途掉电或者复位,芯片会回到默认状态,所以上电后要在主循环里加一个周期性校验,检测芯片是否还处于正常模式。

电压读取函数返回的是裸 ADC 码,需要乘以步进电压(电压 ADC 的满量程是 5.25V,除以 2 的 14 次方,大约是 0.32mV/LSB)换算成毫伏。电流读取函数里,电流 ADC 是 16 位,有符号数,同样要按采样电阻的阻值换算,我在驱动里加了一个参数校准接口,产测时通过标准源校准放大倍数。

3.3 保护逻辑与 SOC 估算落地

保护逻辑分两层:硬件保护和软件保护。硬件保护由 BQ76920 内部的比较器实现,配置阈值和延迟后,即使 MCU 死机,芯片也能独立关断 FET,这是最后一道防线。软件保护则在 MCU 里实现,响应略慢,但可以附加更多条件判断,比如“连续 3 次采样都超阈值才触发”,用来避免瞬时干扰导致的误动作。

我重点说一下过流保护和短路保护的配置差异。BQ76920 的过流保护(OCD)和短路保护(SCD)都通过外部电阻分压配置阈值,延迟通过内部比较器的时间常数设定。过流保护的延迟可以设长一点,比如 100ms 左右,因为短时间的浪涌电流(比如电机启动瞬间)不应该触发保护;短路保护的延迟必须极短,目标是在 MOSFET 和线缆承受不住之前切断回路。这里有一个实际问题:短路电流很大,采样电阻上的压降瞬间超过比较器阈值,芯片能在几十微秒内关断 FET,这时候 MCU 根本来不及反应,所以短路保护必须完全依赖硬件保护链路,MCU 只负责在收到 ALERT 中断后记录故障状态。

SOC 估算是另一个重头戏。我的方案是开路电压法(OCV)加安时积分法的组合:系统上电静止时,读取电芯电压通过 OCV-SOC 查表得到初始 SOC;运行过程中,对电流 ADC 采样做积分,实时推算 SOC;检测到充电完成条件(电压达到截止电压且电流降到涓流阈值)时,把 SOC 强制校准到 100%。这个方法在大多数场景下精度足够,关键是电池厂商提供的 OCV-SOC 曲线必须准确,我建议不要只依赖手册里的通用曲线,最好用自己的电芯实测拟合,不然 SOC 在中间平台区会明显漂移。

3.4 通信协议与上位机交互

通信协议我用了 Modbus RTU 的简化版本,物理层走 UART,波特率 115200,8 位数据位、1 位停止位、无校验。选择 Modbus 而不是自定义协议,是因为上位机工具成熟,PC 上用现成的 Modbus 调试软件就能看到所有寄存器,不需要单独开发上位机。通信帧分成两类:读现场数据(单体电压、总压、电流、温度、SOC、状态字)和写配置参数(保护阈值、均衡开关、SOC 校准)。

上位机交互的实际体验是调试阶段最有价值的部分。硬件调通之后,我把所有关键数据映射到 Modbus 寄存器里,用调试软件盯着电压和电流曲线,能够非常直观地看到保护触发时刻的系统行为。比如有一次放电保护误触发,我从软件曲线里看到电流波形上有一个几百毫秒的尖峰,怀疑是负载启动浪涌,后来把过流延迟从 100ms 调到 200ms,问题就消失了。如果没有这些曲线,这种问题很难定位。

4. 常见问题与排查技巧实录

4.1 BQ76920 初始化失败或通信时好时坏

这个问题的出现频率非常高,排查方向集中在三个地方:I2C 地址、上拉电阻、电平匹配。前面提过,BQ76920 的地址是 0x08,如果你用硬件 I2C 发现通信不稳定,先用逻辑分析仪抓波形确认设备是否应答,如果应答正常但还是报错,检查 I2C 上拉电阻是不是太大,我习惯用 2.2kΩ 上拉到 3.3V,在 400kHz 下波形很干净。

电平匹配方面,BQ76920 的 REGOUT 电压不一定是 3.3V,手册上标称 2.5V~3.6V 之间,如果 MCU 的 I2C 引脚是 3.3V 电平,而 BQ76920 的 REGOUT 实测只有 2.8V,两者直接连接虽然一般能工作,但长时间运行有隐患。我在设计时加了电平转换电路,确保两边信号电平一致,这个问题的确在高温测试中暴露过,所以建议直接照做。

4.2 电压采样不准,偏差还各不相同

电压采样不准首先要排除硬件问题:检查每节电芯的 RC 滤波电阻和电容是否焊接正确、采样线是否虚焊,然后用万用表实测电芯电压跟 BQ76920 读到的值对比。如果固定偏差在几十毫伏,可以通过芯片自带的校准寄存器做增益和偏移校准。BQ76920 提供了电压校准通道,我给每节电芯留了一个校准系数,产测时用标准源逐个校准写入 Flash。

有一个容易忽略的点:BQ76920 的电压 ADC 参考电压是内部带隙基准,它的精度受温度影响。如果设备工作环境温差大,实测下来电压读数会随温度漂移。我的做法是在软件里加了一个温度补偿表,按照环境温度对采样结果做二次修正,经过补偿后,全温区电压误差可以控制在 ±10mV 以内。

4.3 电流数据跳变、SOC 计算不准

电流采样跳变大部分时候是 Layout 问题,也就是采样回路里混入了功率电流。这时要检查 SRP/SRN 走线是否严格按照开尔文连接,如果已经做了还是跳,可以在软件里加一个滑动平均滤波,把采样频率提高后取平均值,也能很大程度上改善。

SOC 不准跟电流精度强相关。安时积分法的误差会随着时间累积,就算电流零点漂移只有几十毫安,连续工作十几小时后,积分误差也能达到几十安时。所以必须做零点校准:在充放电 FET 关闭、确认回路无电流的时候,记录电流 ADC 的偏移值,作为零电流基准。这个校准每次从待机状态进入工作状态之前都执行一次,能显著提升 SOC 长时间稳定性。

4.4 充放电 MOS 管发热严重

MOS 管发热,先别急着换更大封装的管子,先量栅极驱动电压。BQ76920 的 CHG/DSG 引脚通过上拉电阻接到电池堆电压,如果上拉电阻选得太大,驱动电压建立速度慢,MOS 管在开关切换瞬间会长时间处在放大区,发热量剧增。我把上拉电阻从 100kΩ 改成 10kΩ 之后,发热问题基本消失。

还有一个原因是 MOS 管选型不当。BMS 里的 MOS 管工作状态是常通型,只关心 Rds(on) 和热阻,但很多人习惯用开关电源里的型号,开关损耗参数倒挺好,导通电阻却偏大。放电回路里,应该选 Rds(on) 尽量小、栅极电容适中的管子,比如常见的 AON7410 这类低压大电流 NMOS。

5. 关于量产和商业化的几点经验

5.1 可制造性设计要提前想

原理图调通、PCB 打样验证、软件跑完,不代表项目结束,做商业用途还差“可制造性”这一环。我在项目后期专门做了一次器件选型审查,把所有物料的封装、供货渠道、价格都重新过了一遍。有些器件实验室阶段用着挺好,但批量采购时要么交期长,要么价格离谱,必须换成常规替代料。比如采样电阻选型,我一开始用的是某品牌特殊封装合金电阻,后来因为供货问题换成了更常见的 2512 封装。选型审查这件事,越早做越好,等产品定型再换料,光是重新验证就够折腾一个月。

PCB 上要预留足够的测试点。产测阶段,自动化测试设备要接触电压采样点、电流采样点、通信接口、FET 控制信号,如果没有预先设计测试点,探针没地方扎,产线效率会非常低。我建议至少把每节电芯采样点、总压、GND、I2C 时钟和数据、UART TX/RX 都引到测试点阵列上。

5.2 产测流程怎么定

量产测试的项目决定了产品到客户手里后的表现。我的产测流程包括:空载电压自检(验证采样链路)、校准(电压和电流零点、增益)、FET 开关功能测试(分别测试充电和放电 MOS 能否正常打开和关闭)、保护功能抽测(通过模拟信号触发过压保护,验证硬件保护链路)、老化测试(小批量抽检,带负载跑 4 小时)。

其中校准是最耗时间的环节,我把电压校准做成了半自动流程:测试设备读取 BQ76920 的采样值,与标准源比较,自动计算校准系数写入芯片。整条产线测试时间控制在 30 秒以内,效率还能接受。

5.3 文档说明的价值

这套资料里包含的文档说明,我觉得比源码本身还重要。文档里除了原理图和 PCB 设计说明,我还整理了每颗关键器件的选型依据、BQ76920 寄存器配置表、软件模块说明、Modbus 寄存器协议表、产测操作手册。这些文档的价值在于:三个月后自己回来看能快速进入状态,新同事接手不用从零摸索,客户审核时也能证明产品设计有完整的工程依据。

特别是寄存器配置表,我把每个保护阈值参数都换算成了电压/电流值,并备注了出厂默认值和推荐值范围。现场调试的时候,别人只需要对照表格修改参数,不用担心去翻数据手册重新算一遍。

最后再分享一个小经验:无论方案做得多完整,一定要留一个恢复出厂设置的功能。现场调试把参数改乱了,或者电池规格换了一个型号,一键恢复出厂参数能省掉大量沟通成本。这个功能实现起来很简单,在 Flash 里存一个校验标志,检测到标志异常或者接收到恢复命令时,把默认参数表重新加载一遍。就是这个简单功能,帮我在交付后的维护里省了无数趟远程指导。

本文还有配套的精品资源,点击获取

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

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

立即咨询