news 2026/5/30 22:09:51

基于STM的BMS毕业设计:从状态机原理到电池管理实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
基于STM的BMS毕业设计:从状态机原理到电池管理实战


基于STM的BMS毕业设计:从状态机原理到电池管理实战

摘要:许多高校学生在完成“基于STM的BMS毕业设计”时,常因缺乏对状态机(State Machine)与电池管理系统(BMS)协同逻辑的理解,导致系统鲁棒性差、SOC估算不准或通信异常。本文从技术科普角度出发,详解如何利用状态机规范充放电、均衡、故障处理等核心流程,结合STM32硬件平台实现模块化解耦设计。读者将掌握可复用的状态机架构、关键代码实现及调试技巧,显著提升系统稳定性与答辩表现。


1. BMS 核心功能痛点:为什么“保护”总慢半拍?

本科毕设里,BMS 常被简化为“采集电压→判断阈值→关闭 MOS”。看似三步,落地却频发“鬼跳”:

  • 过充保护响应延迟
    采样周期 100 ms,ADC 滤波 32 点平均,再叠加软件去抖,延迟轻松突破 300 ms;而高倍率充电时 1 s 内电压可爬升 50 mV,极易触发二次保护。

  • 状态跳变混乱
    if-else硬编码:

    if(v>4.2) state=OV; else if(v<2.8) state=UV; else state=NORMAL;

    当电压在 4.19 ↔ 4.21 V 抖动,状态机会在 OV ↔ NORMAL 之间高频翻转,继电器“哒哒”作响,最终黏连失效。

  • 均衡与 SOC 估算耦合
    均衡开启后电流路径变化,若 SOC 算法仍按静置模型计算,误差 8 % 司空见惯,答辩时被一句“误差为什么这么大”问倒。

一句话:缺少“确定性”与“可验证性”;而状态机正是给系统带来“确定性”的银弹。



2. 状态机选型:FSM 还是 HSM?

维度有限状态机 FSM层次状态机 HSM
状态数量扁平,~15 个树状,可复用父状态
代码量随状态指数增长线性增长
扩展性新增状态需改表子状态继承父行为
典型实现二维查表QP™、Miro Samek 算法

BMS 场景需要“充电子状态”与“放电子状态”复用同一“温度保护”逻辑,HSM 的“行为继承”天然契合;而 STM32F103C8T6 主频 72 MHz,QP-nano 实测 1 kHz 调度 CPU 占用 < 3 %,资源绰绰有余。故本文以HSM 为理论骨架,轻量级 C 实现为目标,既保留层次优势,又避开 RTOS 依赖。


3. 基于 STM32 HAL 的轻量级 HSM 实现

3.1 状态机骨架

/* bsm.h Battery State Machine */ typedef enum掀动事件 { EV_ENTRY, EV_EXIT, EV_INIT, EV_TICK_10ms, EV_CELL_OVP, EV_CELL_UVP, EV_TEMP_OTP, EV_USER_CHG_ENABLE, EV_USER_CHG_DISABLE, /* ... */ } Event; typedef struct State { char const *name; void (*dispatch)(struct State *me, Event e); /* 父状态指针,NULL 表示顶层 */ struct State *super; } State; /* 全局上下文 */ typedef struct { State *state; /* 当前活动状态 */ uint16_t cell_mV[14]; /* 电芯电压 */ int8_t temp_dC[4]; /* 温度,单位 0.1 ℃ */ uint8_t soc_per; /* SOC % */ } BmsCtx; extern BmsCtx bms;

3.2 状态切换宏(带日志)

#define TRANS(target_) \ do{ \ printf("@%lu S:%s->%s\r\n", HAL_GetTick(), \ bms.state->name, (target_)->name); \ bms.state->dispatch(bms.state, EV_EXIT); \ bms.state = (target_); \ bms.state->dispatch(bms.state, EV_ENTRY); \ }while(0)

3.3 顶层状态实现(节选)

static void Top_dispatch(State *me, Event e){ switch(e){ case EV_TICK_10ms: /* 广播到子状态 */ if(bms.state->super) bms.state->super->dispatch(me, e); /* 采样与滤波 */ ADC_ScanCells(); if(CellMax_mV() > 4200) bms.state->dispatch(bms.state, EV_CELL_OVP); break; } }

3.4 充电状态层次

Top └─ Charging ├─ CC (恒流) ├─ CV (恒压) └─ Taper

当任意电芯触发 OVP,Charging父状态统一处理,子状态无需重复代码:

static void Charging_dispatch(State *me, Event e){ switch(e){ case EV_CELL_OVP: TRANS(&Fault_ovp); return; /* 事件已处理 */ case EV_ENTRY: CHG_MOS_ON(); return; case EV_EXIT: CHG_MOS_OFF(); return; } /* 其余事件给子状态 */ if(me->super) me->super->dispatch(me, e); }

3.5 SOC 更新回调(解耦)

static void CC_dispatch(State *me, Event e){ switch(e){ case EV_TICK_10ms: CoulombCounter_Update(CHG_CURRENT_MA); if(ABS(CHG_CURRENT_MA) < 50) TRANS(&Charging_cv); break; } }

通过事件驱动,SOC 算法与状态机完全解耦;若后期换用 Kalman 滤波,仅需替换CoulombCounter_Update()内部实现,状态表纹丝不动。


4. 安全性与性能:让数字说话

测试项条件结果
状态切换延迟示波器抓取 GPIO 边沿92 µs(含 ADC 判断)
CPU 占用1 kHz 调度,72 MHz2.7 %
看门狗复位间隔IWDG 250 ms0 次误复位
ADC 采样抗噪注入 200 mV 峰峰值 100 kHz电压误差 < 5 mV

关键代码:双缓冲 DMA + 中位值平均

#define ADC_BUF_LEN 32 static uint16_t adc1_buf[ADC_BUF_LEN]; HAL_ADC_Start_DMA(&hadc1, (uint32_t*)adc1_buf, ADC_BUF_LEN); uint16_t ADC_GetMedian(void){ uint16_t tmp[ADC_BUF_LEN]; memcpy(tmp, adc1_buf, sizeof(tmp)); sort_u16(tmp, ADC_BUF_LEN); return tmp[ADC_BUF_LEN/2]; /* 中位值 */ }

中位值滤波对脉冲干扰抑制优于算术平均,且无需乘除,CM3 单周期移位完成。


5. 生产级避坑指南

  1. 状态持久化
    断电瞬间正在均衡,重新上电应恢复均衡。将bms.state枚举索引CRC8一并存入 STM32 备份寄存器(20 B),上电校验通过后TRANS()恢复,否则进入Fault_unknown

  2. 事件队列溢出
    使用环形队列保存外部中断事件;若队列满,丢弃最旧事件而非最新,保证“故障事件优先”。

  3. 调试可视化
    通过 SWO 以 225 kHz 输出压缩事件码,上位机解析后实时绘制状态树,答辩现场一秒出图,老师直呼专业。

  4. 代码 Clean 原则

    • 一个函数只做一件事:Charging_cv()仅处理恒压逻辑,不插手温度。
    • 宏全部大写,TRANS()含括号,避免运算符优先级悲剧。
    • 所有魔法数字收拢到bms_config.h,方便后续移植到 STM32G0。


6. 结语与展望

状态机让 BMS 从“一坨 if”升级为“可证明的确定性自动机”,配合 STM32 的丰富外设,本科毕设也能跑出工业级节奏。下一步,不妨思考:

  • 如何扩展同一套 HSM 支持多节电池串并联
    提示:把“单节状态”抽象为复合状态区域(region),每条 region 独立运行,再引入“系统级仲裁状态”处理环流、反向充电等场景。

  • 是否考虑把代码开源到 GitHub?
    附上一份单元测试(基于 CMocka)与硬件在环(HIL)脚本,下一个 star 也许就来自未来的面试官。

毕业设计不是终点,让电池组更安全、更长寿,才是工程师的持久浪漫。祝调试顺利,答辩高分!


版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/30 8:31:14

3步打造完美歌词体验:ESLyric-LyricsSource全功能配置指南

3步打造完美歌词体验&#xff1a;ESLyric-LyricsSource全功能配置指南 【免费下载链接】ESLyric-LyricsSource Advanced lyrics source for ESLyric in foobar2000 项目地址: https://gitcode.com/gh_mirrors/es/ESLyric-LyricsSource 在数字音乐聆听体验中&#xff0c;…

作者头像 李华
网站建设 2026/5/29 2:36:35

101. 对称二叉树

101. 对称二叉树 简单 给你一个二叉树的根节点 root &#xff0c; 检查它是否轴对称。 示例 1&#xff1a; 输入&#xff1a;root [1,2,2,3,4,4,3] 输出&#xff1a;true 示例 2&#xff1a; 输入&#xff1a;root [1,2,2,null,3,null,3] 输出&#xff1a;false 提示&…

作者头像 李华
网站建设 2026/5/29 0:46:01

OpenWRT应用商店安装失败解决方案:路由器软件中心配置教程

OpenWRT应用商店安装失败解决方案&#xff1a;路由器软件中心配置教程 【免费下载链接】istore 一个 Openwrt 标准的软件中心&#xff0c;纯脚本实现&#xff0c;只依赖Openwrt标准组件。支持其它固件开发者集成到自己的固件里面。更方便入门用户搜索安装插件。The iStore is a…

作者头像 李华
网站建设 2026/5/28 15:50:41

微信社交关系管理新方案:WechatRealFriends使用指南

微信社交关系管理新方案&#xff1a;WechatRealFriends使用指南 【免费下载链接】WechatRealFriends 微信好友关系一键检测&#xff0c;基于微信ipad协议&#xff0c;看看有没有朋友偷偷删掉或者拉黑你 项目地址: https://gitcode.com/gh_mirrors/we/WechatRealFriends …

作者头像 李华
网站建设 2026/5/28 15:50:38

解密 Xamarin.Forms 中嵌入式资源的加载与使用

在 Xamarin.Forms 开发中,如何正确加载嵌入式资源(如图片)是一个常见且容易困扰开发者的问题。本文将通过一个实际案例,详细解释如何在 Xamarin.Forms 应用中正确地加载嵌入式图片资源,并解决常见的错误。 问题背景 假设我们有一个 Xamarin.Forms 项目,其中包含一个名为…

作者头像 李华
网站建设 2026/5/28 15:50:37

3种局域网游戏联机方案:突破无网环境多人游戏限制

3种局域网游戏联机方案&#xff1a;突破无网环境多人游戏限制 【免费下载链接】SteamEmulator MIRROR REPO - Credits : Mr. Goldberg. Steam emulator that emulates Steam online features. Lets you play games that use the Steam multiplayer APIs on a LAN without steam…

作者头像 李华