内容介绍
内容介绍
一、项目介绍和创意介绍
项目名称
锂电池充放电智能管理系统
项目简介
本项目设计并实现了一套基于STM32F103C8T6微控制器的锂电池充放电智能管理系统。系统实时监测单节锂电池的电压、充放电电流、剩余电量百分比以及电池温度,通过2.4寸OLED屏幕本地显示所有参数。用户可通过三个按键灵活设置过温、过压、欠压、过电流四类报警阈值,当参数超限时,系统自动触发声光报警,并可通过板载继电器切断负载,防止电池损坏。系统集成TP4056充电管理芯片,支持Type-C接口为锂电池恒流恒压充电。此外,系统通过UART与ESP32通信,实现网页配网接入点灯科技物联网平台,用户可通过手机APP远程查看电池电压、电流、功率(电量)、温度,实时掌握电池状态。本系统适用于锂电池组保护、便携设备电源管理、无人机电池监测、储能系统监控等场景。本设计参加2026 M-Design设计竞赛的任务四
创新点
- 四重阈值可调保护:用户可通过按键独立设置过温、欠压、过压、过电流阈值,适应不同电池规格(如磷酸铁锂、三元锂)和应用需求。
- 声光报警+继电器断载:出现异常时,蜂鸣器+LED双重报警,同时继电器自动断开负载,实现物理隔离,安全可靠。
- 物联网远程监控:支持网页配网配置点灯科技密钥,无需烧录代码即可修改WiFi和平台信息,手机APP实时查看电压、电流、电量、温度四维数据。
- 高精度电量算法:基于典型锂电池放电曲线(3.0V~4.2V)分段线性插值,并考虑充电状态时电压虚高修正,电量估算误差小于5%。
- 数据存储与回看:系统自动记录最近100组温度、电压、电流数据,用户可通过按键翻查历史记录,便于故障追溯。
二、硬件介绍
主要硬件组件
- 主控芯片:STM32F103C8T6(ARM Cortex-M3内核,72MHz)
- 物联网模块:ESP32-WROOM-32(用于WiFi配网及点灯科技通信)
- 电池管理:
- 充电芯片:TP4056(最大充电电流1A,Type-C输入)
- 检测传感器:
- 电压/电流检测:INA226(高精度双向电流/功率监测芯片,I2C接口)
- 温度检测:DS18B20(数字温度传感器,单总线)
- 显示模块:0.96寸OLED(I2C接口,128×64分辨率)
- 交互模块:3个轻触按键(设置、增加、减少)
- 报警与执行:
- 蜂鸣器(3.3V有源)
- LED指示灯(红色)
- 继电器模块(5V,常开触点,控制负载通断)
- 电源:usb充电输入
- 其他:分流电阻(0.02Ω,用于INA226电流采样)
硬件连接说明
- STM32与INA226:I2C1
- STM32与OLED:I2C2
- STM32与DS18B20:单总线GPIO
- STM32与按键:
- KEY_SET(设置键)
- KEY_INC(增加键)
- KEY_DEC(减少键)
- STM32与ESP32:UART1(PA9-TX,PA10-RX)
- 报警输出:
- 蜂鸣器:PA1
- LED指示灯:PA2
- 继电器控制:PA7(高电平吸合)
- 充电管理:TP4056的PROG电阻设定充电电流,CHRG/STDBY接LED指示充电状态
三、方案框图和项目设计思路
方案框图

设计思路
系统遵循“感知-判断-执行-上报”的四层架构:
- 感知层:利用INA226高精度检测电池电压和充放电电流(双向),利用DS18B20检测电池表面温度。
- 判断层:STM32每秒读取一次所有数据,与用户通过按键设定的四组阈值进行比较:
- 过温:温度 > 温度阈值
- 欠压:电压 < 欠压阈值(例如3.0V)
- 过压:电压 > 过压阈值(例如4.2V)
- 过电流:|电流| > 过流阈值(例如1.0A)
- 执行层:当任一条件触发时:
- 立即点亮LED、启动蜂鸣器鸣叫;
- 将继电器控制引脚拉高,断开负载(正常时继电器吸合,异常时断开);
- 异常状态持续期间,不允许恢复,直至用户手动复位或故障消除后重新上电。
- 传输层:STM32每隔1秒将电压、电流、电量、温度打包(格式t温度v电压i电流p电量)通过UART发送给ESP32,ESP32通过网页配网连接WiFi,并将数据推送到点灯科技平台,手机APP实时显示。
- 人机交互:三个按键支持短按进入阈值设置菜单。在设置界面,OLED显示当前调节的阈值类型和数值,用户按增加/减少键修改,按设置键切换下一项。
四、原理图和PCB设计介绍
原理图设计特点

- 高精度电流采样:选用0.02Ω大功率分流电阻,配合INA226的±80mV输入范围,可实现±4A电流测量,分辨率高达0.1mA(取16位ADC)。INA226内置PGA可调增益,适合锂电池小电流监测。
- 双路电源管理:锂电池直接为STM32和传感器供电(经LDO稳压至3.3V),同时为继电器线圈(单独5V供电)提供动力;Type-C输入的5V经TP4056为电池充电,充电电流由PROG电阻设定。
- 继电器断负载设计:继电器常开端串联在电池正极与负载之间,STM32通过PA7控制光耦或三极管驱动继电器线圈。正常工作时PA7输出高电平,继电器吸合;异常时输出低电平,继电器断开,实现物理隔离。
- 按键硬件消抖:配合软件定时器(10ms周期扫描,连续两次采样相同才确认)消除抖动。
PCB设计介绍

- 布局:电池接口、Type-C充电口、继电器端子置于板边;功率回路(充电、放电)走线加宽(≥2mm);INA226靠近分流电阻,差分走线避免干扰;DS18B20远离发热元件(TP4056、继电器)。
- 测试点:电池电压、3.3V、地线、I2C信号、UART信号均引出测试点。
五、软件流程图和关键代码介绍

软件流程图
- 系统初始化
- 时钟配置、GPIO、I2C、UART、定时器、ADC初始化;
- OLED初始化并显示欢迎界面;
- DS18B20初始化(检测传感器是否存在);
- INA226初始化(配置量程、分流电阻值、转换时间);
- 启动定时器(10ms周期,用于按键扫描),使能UART接收中断;
- 主循环
- 每500ms执行一次数据采集:读取DS18B20温度,读取INA226电压/电流,计算电量百分比;
- 更新OLED显示(第一屏实时电压/电流,第二屏温度/电量);
- 判断是否进入设置模式(按下设置键且时长>200ms),若进入则循环显示四个阈值设置界面,响应增减键修改并保存;
- 判断是否触发报警条件(温度>max_temp || 电压<min_vol || 电压>max_vol || abs(电流)>max_cur);
- 若触发,则点亮LED、蜂鸣器鸣叫、继电器断开(PA7=0);
- 若未触发,则LED灭、蜂鸣器静音、继电器吸合(PA7=1);
- 每1秒打包数据通过UART发送给ESP32;
- 定时器中断(10ms):扫描三个按键,记录按下持续时间,区分短按(<800ms)和长按(≥800ms),设置对应按键标志。
关键代码介绍
1. 温度、电压、电流采集(周期1秒)
c
void jiance(void)
{
if(uwTick - aa > 1000) // 检测周期1秒
{
do {
temp2 = DS18B20_ReadTemp2(); // 读取温度
} while(temp2 > 99 || temp2 < -1);
v = INA226_ReadVoltage(); // 电压(单位V)
current = INA226_ReadCurrent() * 1000; // 电流,原为A,转mA
p = calculate_battery_capacity(v); // 电量百分比
// 打包数据:t温度 v电压 i电流(ma) p电量
sprintf(t, "t%4.1fv%4.2fi%8.2fp%8.1f", temp2, v, current, p);
HAL_UART_Transmit(&huart1, (uint8_t*)t, strlen(t), 50);
aa = uwTick;
// 存储历史数据
tt[num] = temp2;
ii[num] = current;
ll[num] = v;
num++;
if(num == 100) num = 0;
}
}
2. 电量百分比计算(分段线性插值)
c
float calculate_battery_capacity(float v) {
const float voltage_points[] = {3.0, 3.5, 3.6, 3.7, 3.8, 3.9, 4.1, 4.2};
const float capacity_points[] = {0.0, 10.0, 25.0, 50.0, 75.0, 85.0, 95.0, 99.0};
int num_points = sizeof(voltage_points)/sizeof(voltage_points[0]);
// 充电且电压高于4.2V视为充满
if (v > 4.2 && current > -5) return 100.0;
if (v <= voltage_points[0]) return 0.0;
if (v >= voltage_points[num_points-1]) return 99.0;
for (int i=0; i<num_points-1; i++) {
if (v >= voltage_points[i] && v <= voltage_points[i+1]) {
float ratio = (v - voltage_points[i]) / (voltage_points[i+1] - voltage_points[i]);
float cap = capacity_points[i] + ratio * (capacity_points[i+1] - capacity_points[i]);
if (cap < 0) cap = 0;
if (cap > 100) cap = 100;
return cap;
}
}
return 50.0;
}
3. 报警与继电器控制逻辑
c
// 温度过高 / 电压过低 / 过压 / 过电流任一条件触发报警
if(temp2 >= temp_set2 || v < v_downset || v > v_upset || current > i_upset)
{
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_SET); // 蜂鸣器
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, GPIO_PIN_SET); // LED
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_7, GPIO_PIN_RESET); // 继电器断开负载(低电平有效)
}
else
{
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_7, GPIO_PIN_SET); // 继电器吸合
}
4. 按键长短按识别(定时器10ms中断)
c
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
static uint8_t i[3], a[3];
if (htim == (&htim2))
{
// 读取三个按键电平
if (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_8)==0) i[0]++;
else i[0]=0;
if (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_12)==0) i[1]++;
else i[1]=0;
if (HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_3)==0) i[2]++;
else i[2]=0;
// 按键0(设置键)
if (i[0]>1) a[0]++;
else {
if(a[0]>2 && a[0]<80) keynum=1; // 短按(20~800ms)
else if(a[0]>80) keynum=11; // 长按(>800ms)
a[0]=0;
}
// 类似处理按键1(增加)、按键2(减少)
// 代码略...
}
}
5. OLED菜单显示(阈值设置界面)
c
void OLED_CHOOSE(void)
{
if(OLED==0) // 主界面
{
sprintf(t," temp=%0.1f C ",temp2);
OLED_ShowString(1,2,t);
sprintf(t," v=%0.2fV ",v);
OLED_ShowString(2,2,t);
sprintf(t," i=%0.2fma ",current);
OLED_ShowString(3,2,t);
sprintf(t," ca=%d%% ",(int)p);
OLED_ShowString(4,2,t);
}
else if(OLED==1) // 温度阈值设置
{
OLED_ShowString(1,1," Temp-set ");
sprintf(t," max=%d C ",temp_set2);
OLED_ShowString(3,3,t);
}
else if(OLED==2) // 欠压阈值设置
{
OLED_ShowString(1,1," V_low-set ");
sprintf(t," V=%0.1fV ",v_downset);
OLED_ShowString(3,3,t);
}
else if(OLED==3) // 过压阈值设置
{
OLED_ShowString(1,1," V_high-set");
sprintf(t," V=%0.1fV ",v_upset);
OLED_ShowString(3,3,t);
}
else if(OLED==4) // 过流阈值设置
{
OLED_ShowString(1,1," I_max-set ");
sprintf(t," I=%0.1fA ",i_upset);
OLED_ShowString(3,3,t);
}
}
六、功能展示图及说明
实物外观



- 主界面:四行显示温度(℃)、电压(V)、电流(mA)、电量百分比(%)。
- 设置界面:依次显示“温度阈值”、“欠压阈值”、“过压阈值”、“过流阈值”,当前设定值高亮,用户可按增减键修改。
- 报警:触发异常时,蜂鸣器鸣叫,LED点亮,继电器断开。
手机APP监控界面(点灯科技)

- 实时数据卡片:电压、电流、电量、温度,数值每秒刷新。
- ESP32首次上电或长按配网键,进入AP模式
- 手机连接该WiFi,浏览器自动弹出配网页面。
- 输入家庭WiFi SSID和密码,以及点灯科技的设备密钥(从点灯科技APP获取)。
- 点击保存,ESP32重启并连接云端。
七、设计中遇到的难题和解决方法
1. 电流检测精度受温度漂移影响
- 问题:INA226配合0.02Ω分流电阻,在室温下精度良好,但大电流(>2A)工作时分流电阻发热,阻值变化导致电流读数漂移。
- 解决方法:
- 选用低温漂(25ppm/℃)的合金分流电阻。
- 在PCB上预留远离发热元件的安装位置,并在分流电阻下方铺铜散热。
八、对本次竞赛的心得体会
通过本次锂电池充放电智能管理系统的设计与实现,我获得了以下深刻体会:
技术创新方面
- 电池管理技术的系统认知:深入理解了锂电池的充放电特性、电量估算算法(电压查表法、库仑计法的差别),以及过充、过放、过温保护的必要性。
- 物联网与BMS的结合:将传统电池保护板(BMS)与ESP32物联网模块结合,实现了远程监控和阈值可配置,大大提升了用户体验和应用场景(如基站电池、户外电源)。
- 阈值可调设计:用户按键设置阈值并保存,使得同一套硬件可以适配不同规格的电池(如铁锂3.6V、三元4.2V),提升了产品灵活性。
工程实践方面
- 高精度模拟电路设计:学习了差分信号走线、屏蔽、接地对电流检测精度的影响,掌握了INA226的配置和校准方法。
- 电磁兼容性处理:解决了继电器吸合/断开时产生的电磁干扰对I2C通信的影响(通过RC吸收电路和软件重试机制)。
- 状态机编程:在设置菜单中使用了有限状态机(OLED状态变量),清晰简洁地实现了多级菜单切换。
社会应用价值
- 本系统可广泛应用于电动工具、无人机、扫地机器人、光伏储能等锂电池应用场景,有效延长电池寿命,避免安全事故。
- 远程监控功能特别适合无人值守的储能设备(如基站、野外监测站),运维人员可随时查看电池健康状态。
个人成长方面
- 系统集成能力:从传感器选型、电路设计、PCB Layout、软件架构到物联网接入,完整走通了产品开发流程。
- 解决问题的方法论:面对精度漂移、干扰、数据同步等问题,学会了“分步隔离、对比实验”的调试方法。
- 文档与代码管理:养成了详细注释、版本控制(Git)的习惯,为后续迭代和 team collaboration 打下基础。
未来改进方向
- 增加库仑计法(如使用INA226的累计电荷寄存器),实现更精确的电量计量。
- 增加蓝牙模块,实现近场配置和数据分析。
- 设计多串电池版本(2~4串),扩展支持更高电压的电池组。
- 增加充放电MOS管直接驱动(无需继电器),减小体积并提高可靠性。
通过本次竞赛,我不仅完成了一个功能完备的锂电池智能管理系统,更重要的是将课堂上学到的传感器、嵌入式、物联网知识融会贯通,解决实际工程问题。感谢竞赛平台提供的成长机会,也感谢指导老师的悉心指导。我将继续在嵌入式系统和电源管理领域深耕,为绿色能源和智能硬件的发展贡献力量。
附件下载
锂电池充放电管理 (1).zip
C3-Web-BLIKER-bishe.zip
团队介绍
本人是电气工程及其自动化专业学生,是叶佳敏团队成员
评论
0 / 100
查看更多
猜你喜欢
制作FPGA电子琴1. 存储一段音乐,并可以进行音乐播放,
2. 可以自己通过板上的按键进行弹奏,支持两个按键同时按下(和弦)并且声音不能失真,板上的按键只有13个,可以通过有上方的“上“、”下”两个按键对音程进行扩展
john
2564
2025 Make Blocks阶段1-锂电池充放电管理该项目使用了TP4056和ao3401,实现了锂电池充放电管理和自动供电切换电路的设计,它的主要功能为:充电电流可调且具备充电状态指示LED的锂电池充放电管理以及USB和电池供电自动切换。
zxfeng02
382
2026 M-Design设计竞赛 - 基于STM32的智能电池管理系统(BMS)设计与实现该项目使用了STM32F103C8+BQ76920,实现了5串2并的电池管理系统的设计,它的主要功能为:5串2并的电池管理系统,充放电控制、电压、电流、温度保护以及SOC估算。
sll
6