编程技术分享

分享编程知识,探讨技术创新

0%

简介:一款高颜值可视化可更换电池21700储能单元电池盒,6S1P免焊接结构,配有带均衡、过温、过流、过压保护的保护板,双XT60接口。

好的,作为一名高级嵌入式软件开发工程师,我将为你详细阐述这款高颜值可视化可更换电池21700储能单元电池盒的嵌入式系统软件设计方案,并提供相应的C代码实现。这个项目确实涵盖了嵌入式系统开发的完整流程,从需求分析到最终的维护升级,我将尽力展示一个可靠、高效、可扩展的系统平台架构。
关注微信公众号,提前获取相关推文

项目背景与需求分析

首先,我们来详细分析这款电池盒的需求:

  1. 高颜值可视化: 这意味着产品外观设计需要美观,并且可能需要通过指示灯、显示屏或其他可视化方式来展示电池状态、保护状态等信息。软件层面需要支持这些可视化元素的驱动和控制。

  2. 可更换电池 21700 储能单元: 核心功能是储能,采用可更换的21700电池,意味着系统需要能够检测电池的连接状态,并适应不同电池的特性(虽然型号相同,但可能存在个体差异)。

  3. 6S1P 免焊接结构: 6S1P 指的是 6 节电池串联,1 节并联。免焊接结构简化了组装和更换过程,但也需要考虑连接的可靠性,软件层面可能需要关注电池连接状态的检测。

  4. 带均衡、过温、过流、过压保护的保护板 (BMS): 这是电池安全和寿命的关键。BMS 需要实时监测电池的电压、电流、温度,并在异常情况下进行保护。软件需要与 BMS 协同工作,读取 BMS 数据,并根据 BMS 的反馈进行相应的控制和显示。均衡功能旨在提升电池组的整体性能和寿命,软件可能需要参与均衡策略的控制或监控。

  5. 双 XT60 接口: XT60 接口是常用的电源连接器,双 XT60 接口可能用于输入和输出,或者并联输出以提供更大的电流能力。软件需要考虑接口的用途,并进行相应的电源管理和控制。

系统架构设计

基于以上需求分析,我将采用分层架构来设计这款嵌入式系统的软件,以提高系统的模块化、可维护性和可扩展性。架构主要分为以下几层:

  1. 硬件抽象层 (HAL - Hardware Abstraction Layer):

    • 目的: 屏蔽底层硬件差异,为上层软件提供统一的硬件接口。
    • 包含模块:
      • GPIO 驱动: 控制 LED 指示灯、按键输入等。
      • ADC 驱动: 读取电池电压、电流、温度传感器的数据。
      • I2C/SPI/UART 驱动: 与 BMS 芯片或其他外设进行通信。
      • 定时器驱动: 提供系统时钟、定时任务和 PWM 控制(例如用于均衡)。
      • 电源管理驱动: 控制电源开关、检测电源状态等。
  2. 设备驱动层 (Device Driver Layer):

    • 目的: 封装具体的硬件设备操作,为上层提供设备相关的服务接口。
    • 包含模块:
      • 电池电压/电流传感器驱动: 读取电池电压和电流数据,并进行数据转换和校准。
      • 温度传感器驱动: 读取温度数据,并进行数据转换和校准。
      • BMS 芯片驱动: 与 BMS 芯片通信,读取 BMS 状态数据 (电压、电流、温度、保护状态、均衡状态等),并发送控制指令 (例如均衡控制)。
      • LED 驱动: 控制 LED 指示灯的亮灭、闪烁等模式。
      • XT60 接口驱动: 检测 XT60 接口的连接状态(如果需要)。
  3. BMS 核心逻辑层 (BMS Core Logic Layer):

    • 目的: 实现 BMS 的核心功能,包括数据处理、状态监控、保护策略、均衡控制等。
    • 包含模块:
      • 数据采集模块: 周期性地从设备驱动层获取电池电压、电流、温度、BMS 状态数据。
      • 数据处理模块: 对采集到的数据进行滤波、平均、校准等处理,计算电池组的总电压、电流、平均温度、温差等关键参数。
      • 状态监控模块: 实时监控电池电压、电流、温度等参数,判断电池是否处于安全工作范围内。
      • 保护模块: 根据状态监控结果,触发过压保护、欠压保护、过流保护、过温保护等保护机制。保护动作可能包括断开输出、报警提示等。
      • 均衡模块: 根据电池电压差异,控制均衡电路进行电池均衡,提升电池组的整体性能和寿命。均衡策略可以是主动均衡或被动均衡,软件需要实现相应的均衡算法和控制逻辑。
      • 告警模块: 当系统检测到异常状态时,产生告警信息,例如过压告警、过温告警、低电量告警等。告警信息可以通过 LED 指示灯、蜂鸣器或其他方式进行提示。
      • 状态估计模块 (可选): 可以进一步扩展,实现电池荷电状态 (SOC) 估算、健康状态 (SOH) 评估等高级功能。
  4. 应用层 (Application Layer):

    • 目的: 实现用户界面的逻辑、系统初始化、任务调度、错误处理等系统级功能。
    • 包含模块:
      • 系统初始化模块: 完成系统启动时的初始化工作,例如硬件初始化、驱动初始化、参数加载等。
      • 主循环模块: 系统的核心控制循环,负责任务调度、数据采集、状态监控、保护处理、用户交互等。
      • 用户界面模块 (LED 控制): 根据系统状态 (例如电量、保护状态、告警状态) 控制 LED 指示灯的显示模式。
      • 错误处理模块: 处理系统运行过程中出现的错误,例如硬件故障、数据异常等。错误处理包括错误检测、错误记录、错误恢复等。
      • 配置管理模块 (可选): 如果需要支持参数配置,可以实现配置管理模块,例如通过串口或上位机软件配置保护阈值、均衡参数等。
      • 通信接口模块 (可选): 如果需要与上位机或其他设备进行通信,可以实现通信接口模块,例如通过 UART、I2C、CAN 等接口进行数据交互。

代码实现细节与C代码示例

接下来,我将针对上述架构中的关键模块,提供详细的代码实现细节和 C 代码示例。由于篇幅限制,我将重点展示核心功能的代码框架和关键算法,并解释代码的设计思路。

1. 硬件抽象层 (HAL)

HAL 层需要根据具体的硬件平台进行适配。假设我们使用的 MCU 是 STM32 系列,并且使用了 STM32 HAL 库。以下是一些 HAL 层的接口定义示例:

hal_gpio.h:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#ifndef HAL_GPIO_H
#define HAL_GPIO_H

typedef enum {
GPIO_PIN_RESET = 0,
GPIO_PIN_SET = 1
} GPIO_PinState;

typedef enum {
GPIO_MODE_INPUT,
GPIO_MODE_OUTPUT,
// ... 其他 GPIO 模式
} GPIO_ModeTypeDef;

typedef enum {
GPIO_SPEED_FREQ_LOW,
GPIO_SPEED_FREQ_MEDIUM,
GPIO_SPEED_FREQ_HIGH,
GPIO_SPEED_FREQ_VERY_HIGH
} GPIO_SpeedTypeDef;

typedef struct {
uint32_t Pin; // GPIO 引脚
GPIO_ModeTypeDef Mode; // GPIO 模式
GPIO_SpeedTypeDef Speed; // GPIO 速度
// ... 其他 GPIO 配置参数
} GPIO_InitTypeDef;

void HAL_GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct);
void HAL_GPIO_WritePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState);
GPIO_PinState HAL_GPIO_ReadPin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);

#endif // HAL_GPIO_H

hal_adc.h:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#ifndef HAL_ADC_H
#define HAL_ADC_H

typedef struct {
uint32_t Resolution; // ADC 分辨率
uint32_t DataAlign; // 数据对齐方式
// ... 其他 ADC 配置参数
} ADC_InitTypeDef;

typedef struct {
uint32_t Channel; // ADC 通道
uint32_t Rank; // 通道转换顺序
uint32_t SamplingTime; // 采样时间
// ... 其他通道配置参数
} ADC_ChannelConfTypeDef;

void HAL_ADC_Init(ADC_TypeDef* ADCx, ADC_InitTypeDef* ADC_InitStruct);
void HAL_ADC_ConfigChannel(ADC_TypeDef* ADCx, ADC_ChannelConfTypeDef* sConfig);
HAL_StatusTypeDef HAL_ADC_Start(ADC_TypeDef* ADCx);
HAL_StatusTypeDef HAL_ADC_PollForConversion(ADC_TypeDef* ADCx, uint32_t Timeout);
uint32_t HAL_ADC_GetValue(ADC_TypeDef* ADCx);
HAL_StatusTypeDef HAL_ADC_Stop(ADC_TypeDef* ADCx);

#endif // HAL_ADC_H

hal_timer.h:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#ifndef HAL_TIMER_H
#define HAL_TIMER_H

typedef struct {
uint32_t Prescaler; // 预分频器
uint32_t CounterMode; // 计数模式
uint32_t Period; // 周期
// ... 其他定时器配置参数
} TIM_InitTypeDef;

void HAL_TIM_Base_Init(TIM_TypeDef* TIMx, TIM_InitTypeDef* Init);
HAL_StatusTypeDef HAL_TIM_Base_Start(TIM_TypeDef* TIMx);
HAL_StatusTypeDef HAL_TIM_Base_Stop(TIM_TypeDef* TIMx);
uint32_t HAL_TIM_GetCounter(TIM_TypeDef* TIMx);

// PWM 相关
typedef struct {
uint32_t Pulse; // 脉冲宽度
uint32_t OCMode; // 输出比较模式
uint32_t OutputState; // 输出状态
// ... 其他 PWM 配置参数
} TIM_OC_InitTypeDef;

void HAL_TIM_PWM_Init(TIM_TypeDef* TIMx, TIM_InitTypeDef* Init);
void HAL_TIM_PWM_ConfigChannel(TIM_TypeDef* TIMx, TIM_OC_InitTypeDef* sConfig, uint32_t Channel);
HAL_StatusTypeDef HAL_TIM_PWM_Start(TIM_TypeDef* TIMx, uint32_t Channel);
HAL_StatusTypeDef HAL_TIM_PWM_Stop(TIM_TypeDef* TIMx, uint32_t Channel);
HAL_StatusTypeDef HAL_TIM_PWM_SetPulse(TIM_TypeDef* TIMx, uint32_t Channel, uint32_t Pulse);

#endif // HAL_TIMER_H

2. 设备驱动层 (Device Driver)

设备驱动层基于 HAL 层接口,实现具体硬件设备的操作。

drv_voltage_sensor.h:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#ifndef DRV_VOLTAGE_SENSOR_H
#define DRV_VOLTAGE_SENSOR_H

#include "hal_adc.h"

typedef struct {
ADC_TypeDef* ADCx;
uint32_t Channel;
float VoltageRatio; // 分压电阻比例
} VoltageSensor_HandleTypeDef;

HAL_StatusTypeDef VoltageSensor_Init(VoltageSensor_HandleTypeDef* sensor);
float VoltageSensor_ReadVoltage(VoltageSensor_HandleTypeDef* sensor);

#endif // DRV_VOLTAGE_SENSOR_H

drv_voltage_sensor.c:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include "drv_voltage_sensor.h"

HAL_StatusTypeDef VoltageSensor_Init(VoltageSensor_HandleTypeDef* sensor) {
ADC_InitTypeDef adc_init;
ADC_ChannelConfTypeDef adc_channel_config;

adc_init.Resolution = ADC_RESOLUTION_12B; // 12 位分辨率
adc_init.DataAlign = ADC_DATAALIGN_RIGHT;
// ... 其他 ADC 初始化参数

HAL_ADC_Init(sensor->ADCx, &adc_init);

adc_channel_config.Channel = sensor->Channel;
adc_channel_config.Rank = ADC_REGULAR_RANK_1;
adc_channel_config.SamplingTime = ADC_SAMPLETIME_28CYCLES;
// ... 其他通道配置参数

HAL_ADC_ConfigChannel(sensor->ADCx, &adc_channel_config);

return HAL_OK;
}

float VoltageSensor_ReadVoltage(VoltageSensor_HandleTypeDef* sensor) {
HAL_ADC_Start(sensor->ADCx);
HAL_ADC_PollForConversion(sensor->ADCx, 10); // 等待转换完成,超时 10ms
uint32_t adc_value = HAL_ADC_GetValue(sensor->ADCx);
HAL_ADC_Stop(sensor->ADCx);

// ADC 值转换为电压值
float voltage = (float)adc_value * 3.3f / 4096.0f * sensor->VoltageRatio; // 假设参考电压 3.3V,12 位 ADC
return voltage;
}

drv_temperature_sensor.h:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#ifndef DRV_TEMPERATURE_SENSOR_H
#define DRV_TEMPERATURE_SENSOR_H

#include "hal_adc.h"

typedef struct {
ADC_TypeDef* ADCx;
uint32_t Channel;
// ... 温度传感器特性参数 (例如 NTC 热敏电阻的 B 值)
} TemperatureSensor_HandleTypeDef;

HAL_StatusTypeDef TemperatureSensor_Init(TemperatureSensor_HandleTypeDef* sensor);
float TemperatureSensor_ReadTemperature(TemperatureSensor_HandleTypeDef* sensor);

#endif // DRV_TEMPERATURE_SENSOR_H

drv_temperature_sensor.c:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include "drv_temperature_sensor.h"
#include <math.h> // 需要用到数学函数

HAL_StatusTypeDef TemperatureSensor_Init(TemperatureSensor_HandleTypeDef* sensor) {
ADC_InitTypeDef adc_init;
ADC_ChannelConfTypeDef adc_channel_config;

adc_init.Resolution = ADC_RESOLUTION_12B; // 12 位分辨率
adc_init.DataAlign = ADC_DATAALIGN_RIGHT;
// ... 其他 ADC 初始化参数

HAL_ADC_Init(sensor->ADCx, &adc_init);

adc_channel_config.Channel = sensor->Channel;
adc_channel_config.Rank = ADC_REGULAR_RANK_1;
adc_channel_config.SamplingTime = ADC_SAMPLETIME_28CYCLES;
// ... 其他通道配置参数

HAL_ADC_ConfigChannel(sensor->ADCx, &adc_channel_config);

return HAL_OK;
}

float TemperatureSensor_ReadTemperature(TemperatureSensor_HandleTypeDef* sensor) {
HAL_ADC_Start(sensor->ADCx);
HAL_ADC_PollForConversion(sensor->ADCx, 10); // 等待转换完成,超时 10ms
uint32_t adc_value = HAL_ADC_GetValue(sensor->ADCx);
HAL_ADC_Stop(sensor->ADCx);

// ADC 值转换为温度值 (这里需要根据具体的温度传感器特性进行转换)
// 例如,如果是 NTC 热敏电阻,可以使用 Steinhart-Hart 方程或 B 值法进行计算
// 简化示例:假设 ADC 值与温度线性相关 (实际应用中需要更精确的转换)
float temperature = (float)adc_value * 100.0f / 4096.0f; // 假设线性关系,简单示例
return temperature;
}

drv_bms_ic.h:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#ifndef DRV_BMS_IC_H
#define DRV_BMS_IC_H

// 假设 BMS 芯片使用 I2C 通信
#include "hal_i2c.h"

typedef struct {
I2C_HandleTypeDef* I2Cx;
uint8_t DeviceAddress;
} BMSIC_HandleTypeDef;

HAL_StatusTypeDef BMSIC_Init(BMSIC_HandleTypeDef* bms_ic);
HAL_StatusTypeDef BMSIC_ReadRegister(BMSIC_HandleTypeDef* bms_ic, uint8_t reg_addr, uint8_t* data);
HAL_StatusTypeDef BMSIC_WriteRegister(BMSIC_HandleTypeDef* bms_ic, uint8_t reg_addr, uint8_t data);

// 读取 BMS 状态信息
typedef struct {
float cell_voltages[6]; // 假设 6 串电池
float current;
float temperature;
uint16_t protection_status; // 位域表示各种保护状态
uint16_t balancing_status; // 位域表示均衡状态
// ... 其他 BMS 状态信息
} BMS_StatusTypeDef;

HAL_StatusTypeDef BMSIC_GetStatus(BMSIC_HandleTypeDef* bms_ic, BMS_StatusTypeDef* status);

// 控制均衡
HAL_StatusTypeDef BMSIC_EnableBalancing(BMSIC_HandleTypeDef* bms_ic, uint8_t cell_index); // 启用指定 cell 的均衡
HAL_StatusTypeDef BMSIC_DisableBalancing(BMSIC_HandleTypeDef* bms_ic, uint8_t cell_index); // 禁用指定 cell 的均衡
HAL_StatusTypeDef BMSIC_EnableAllBalancing(BMSIC_HandleTypeDef* bms_ic); // 启用所有 cell 的均衡
HAL_StatusTypeDef BMSIC_DisableAllBalancing(BMSIC_HandleTypeDef* bms_ic); // 禁用所有 cell 的均衡

#endif // DRV_BMS_IC_H

drv_bms_ic.c:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#include "drv_bms_ic.h"

HAL_StatusTypeDef BMSIC_Init(BMSIC_HandleTypeDef* bms_ic) {
// I2C 初始化 (假设 HAL 层已经完成 I2C 初始化)
return HAL_OK;
}

HAL_StatusTypeDef BMSIC_ReadRegister(BMSIC_HandleTypeDef* bms_ic, uint8_t reg_addr, uint8_t* data) {
return HAL_I2C_Mem_Read(bms_ic->I2Cx, bms_ic->DeviceAddress, reg_addr, I2C_MEMADD_SIZE_8BIT, data, 1, 100); // 超时 100ms
}

HAL_StatusTypeDef BMSIC_WriteRegister(BMSIC_HandleTypeDef* bms_ic, uint8_t reg_addr, uint8_t data) {
return HAL_I2C_Mem_Write(bms_ic->I2Cx, bms_ic->DeviceAddress, reg_addr, I2C_MEMADD_SIZE_8BIT, &data, 1, 100); // 超时 100ms
}

HAL_StatusTypeDef BMSIC_GetStatus(BMSIC_HandleTypeDef* bms_ic, BMS_StatusTypeDef* status) {
// 读取 BMS 状态寄存器,并解析数据
// (具体寄存器地址和数据格式需要参考 BMS 芯片的数据手册)
uint8_t raw_data[32]; // 假设状态数据长度

// 读取电池电压 (假设每个 cell 电压占 2 字节,共 6 cell)
for (int i = 0; i < 6; i++) {
HAL_StatusTypeDef ret = BMSIC_ReadRegister(bms_ic, BMS_VOLTAGE_REG_BASE + i * 2, &raw_data[i * 2]); // 假设电压寄存器地址连续
if (ret != HAL_OK) return ret;
status->cell_voltages[i] = (float)(((uint16_t)raw_data[i * 2 + 1] << 8) | raw_data[i * 2]) * VOLTAGE_LSB_VALUE; // 假设电压 LSB 值
}

// 读取电流 (假设电流占 2 字节)
HAL_StatusTypeDef ret = BMSIC_ReadRegister(bms_ic, BMS_CURRENT_REG, raw_data);
if (ret != HAL_OK) return ret;
status->current = (float)(((uint16_t)raw_data[1] << 8) | raw_data[0]) * CURRENT_LSB_VALUE; // 假设电流 LSB 值

// ... 读取温度、保护状态、均衡状态等 (类似读取电压和电流)

return HAL_OK;
}

HAL_StatusTypeDef BMSIC_EnableBalancing(BMSIC_HandleTypeDef* bms_ic, uint8_t cell_index) {
// 设置均衡控制寄存器,启用指定 cell 的均衡
// (具体寄存器地址和位域需要参考 BMS 芯片的数据手册)
uint8_t reg_data;
HAL_StatusTypeDef ret = BMSIC_ReadRegister(bms_ic, BMS_BALANCING_CTRL_REG, &reg_data);
if (ret != HAL_OK) return ret;

reg_data |= (1 << cell_index); // 设置对应 cell 的均衡使能位
return BMSIC_WriteRegister(bms_ic, BMS_BALANCING_CTRL_REG, reg_data);
}

HAL_StatusTypeDef BMSIC_DisableBalancing(BMSIC_HandleTypeDef* bms_ic, uint8_t cell_index) {
// 设置均衡控制寄存器,禁用指定 cell 的均衡
uint8_t reg_data;
HAL_StatusTypeDef ret = BMSIC_ReadRegister(bms_ic, BMS_BALANCING_CTRL_REG, &reg_data);
if (ret != HAL_OK) return ret;

reg_data &= ~(1 << cell_index); // 清除对应 cell 的均衡使能位
return BMSIC_WriteRegister(bms_ic, BMS_BALANCING_CTRL_REG, reg_data);
}

// ... EnableAllBalancing, DisableAllBalancing 函数类似,操作所有 cell 的均衡使能位

3. BMS 核心逻辑层 (BMS Core Logic)

bms_core.h:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#ifndef BMS_CORE_H
#define BMS_CORE_H

#include "drv_voltage_sensor.h"
#include "drv_temperature_sensor.h"
#include "drv_bms_ic.h"

// 定义保护阈值
#define OVER_VOLTAGE_THRESHOLD 4.25f // 过压保护阈值 (单 cell 电压)
#define UNDER_VOLTAGE_THRESHOLD 3.0f // 欠压保护阈值 (单 cell 电压)
#define OVER_CURRENT_THRESHOLD 5.0f // 过流保护阈值 (电流)
#define OVER_TEMPERATURE_THRESHOLD 60.0f // 过温保护阈值 (温度)
#define UNDER_TEMPERATURE_THRESHOLD 0.0f // 低温保护阈值 (温度)

typedef struct {
VoltageSensor_HandleTypeDef voltage_sensors[6]; // 6 串电池电压传感器
TemperatureSensor_HandleTypeDef temperature_sensors[3]; // 假设 3 个温度传感器 (例如每两串电池一个)
BMSIC_HandleTypeDef bms_ic;
// ... 其他 BMS 核心逻辑层需要的硬件资源句柄
} BMSCore_HandleTypeDef;

HAL_StatusTypeDef BMSCore_Init(BMSCore_HandleTypeDef* bms_core);
void BMSCore_Process(BMSCore_HandleTypeDef* bms_core);

#endif // BMS_CORE_H

bms_core.c:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
#include "bms_core.h"
#include "stdio.h" // 用于 printf 调试信息

HAL_StatusTypeDef BMSCore_Init(BMSCore_HandleTypeDef* bms_core) {
// 初始化电压传感器
for (int i = 0; i < 6; i++) {
if (VoltageSensor_Init(&bms_core->voltage_sensors[i]) != HAL_OK) {
return HAL_ERROR;
}
}
// 初始化温度传感器
for (int i = 0; i < 3; i++) {
if (TemperatureSensor_Init(&bms_core->temperature_sensors[i]) != HAL_OK) {
return HAL_ERROR;
}
}
// 初始化 BMS IC
if (BMSIC_Init(&bms_core->bms_ic) != HAL_OK) {
return HAL_ERROR;
}

return HAL_OK;
}

void BMSCore_Process(BMSCore_HandleTypeDef* bms_core) {
static uint32_t last_process_time = 0;
uint32_t current_time = HAL_GetTick(); // 获取系统时间 (假设 HAL 层提供了 HAL_GetTick 函数)

// 定时执行 BMS 核心逻辑 (例如每 100ms 执行一次)
if (current_time - last_process_time >= 100) {
last_process_time = current_time;

// 1. 数据采集
float cell_voltages[6];
float temperatures[3];
BMS_StatusTypeDef bms_status;

for (int i = 0; i < 6; i++) {
cell_voltages[i] = VoltageSensor_ReadVoltage(&bms_core->voltage_sensors[i]);
}
for (int i = 0; i < 3; i++) {
temperatures[i] = TemperatureSensor_ReadTemperature(&bms_core->temperature_sensors[i]);
}
BMSIC_GetStatus(&bms_core->bms_ic, &bms_status);

// 打印调试信息 (实际应用中可以使用日志系统或上位机监控)
printf("Cell Voltages: %.3fV, %.3fV, %.3fV, %.3fV, %.3fV, %.3fV\r\n",
cell_voltages[0], cell_voltages[1], cell_voltages[2],
cell_voltages[3], cell_voltages[4], cell_voltages[5]);
printf("Temperatures: %.1fC, %.1fC, %.1fC\r\n",
temperatures[0], temperatures[1], temperatures[2]);
printf("Current: %.3fA\r\n", bms_status.current);
printf("Protection Status: 0x%04X\r\n", bms_status.protection_status);
printf("Balancing Status: 0x%04X\r\n", bms_status.balancing_status);

// 2. 状态监控与保护
for (int i = 0; i < 6; i++) {
if (cell_voltages[i] > OVER_VOLTAGE_THRESHOLD) {
printf("Over Voltage Protection triggered on Cell %d\r\n", i + 1);
// 执行过压保护动作 (例如断开输出)
// ...
}
if (cell_voltages[i] < UNDER_VOLTAGE_THRESHOLD) {
printf("Under Voltage Protection triggered on Cell %d\r\n", i + 1);
// 执行欠压保护动作
// ...
}
}

if (bms_status.current > OVER_CURRENT_THRESHOLD) {
printf("Over Current Protection triggered\r\n");
// 执行过流保护动作
// ...
}

for (int i = 0; i < 3; i++) {
if (temperatures[i] > OVER_TEMPERATURE_THRESHOLD) {
printf("Over Temperature Protection triggered on Sensor %d\r\n", i + 1);
// 执行过温保护动作
// ...
}
if (temperatures[i] < UNDER_TEMPERATURE_THRESHOLD) {
printf("Under Temperature Protection triggered on Sensor %d\r\n", i + 1);
// 执行低温保护动作
// ...
}
}

// 3. 均衡控制 (简化的被动均衡示例)
// 检测相邻 cell 电压差,如果超过阈值,则开启均衡
float balance_threshold = 0.05f; // 均衡阈值 50mV
for (int i = 0; i < 5; i++) {
if (cell_voltages[i] - cell_voltages[i + 1] > balance_threshold) {
printf("Balancing Cell %d to Cell %d\r\n", i + 2, i + 1);
BMSIC_EnableBalancing(&bms_core->bms_ic, i + 1); // 假设均衡控制的是高电压 cell
} else if (cell_voltages[i + 1] - cell_voltages[i] > balance_threshold) {
printf("Balancing Cell %d to Cell %d\r\n", i + 1, i + 2);
BMSIC_EnableBalancing(&bms_core->bms_ic, i); // 假设均衡控制的是高电压 cell
} else {
BMSIC_DisableBalancing(&bms_core->bms_ic, i);
BMSIC_DisableBalancing(&bms_core->bms_ic, i+1);
}
}
}
}

4. 应用层 (Application Layer)

main.c:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
#include "main.h"
#include "bms_core.h"
#include "hal_gpio.h" // 假设 HAL 层提供了 GPIO 控制 LED 的接口

BMSCore_HandleTypeDef bms_core_handle;
GPIO_InitTypeDef led_gpio_init;

void SystemClock_Config(void); // 系统时钟配置函数 (需要根据具体 MCU 实现)
void Error_Handler(void); // 错误处理函数

int main(void) {
HAL_Init(); // HAL 库初始化
SystemClock_Config(); // 系统时钟配置

// 初始化 LED GPIO
led_gpio_init.Pin = GPIO_PIN_0; // 假设 LED 连接到 GPIO Pin 0
led_gpio_init.Mode = GPIO_MODE_OUTPUT_PP;
led_gpio_init.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOA, &led_gpio_init); // 假设 LED 连接到 GPIOA

// 初始化 BMS 核心逻辑
// (这里需要根据硬件连接配置具体的 ADC 通道、I2C 地址等参数)
bms_core_handle.voltage_sensors[0].ADCx = ADC1;
bms_core_handle.voltage_sensors[0].Channel = ADC_CHANNEL_0;
bms_core_handle.voltage_sensors[0].VoltageRatio = 10.0f; // 假设分压比 10:1
// ... 初始化其他电压传感器、温度传感器、BMS IC

if (BMSCore_Init(&bms_core_handle) != HAL_OK) {
Error_Handler(); // 初始化失败,进入错误处理
}

while (1) {
BMSCore_Process(&bms_core_handle); // 执行 BMS 核心逻辑

// 用户界面 (LED 控制示例)
// 例如,根据电池状态控制 LED 闪烁频率
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_SET); // LED ON
HAL_Delay(500);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_RESET); // LED OFF
HAL_Delay(500);
}
}

// 系统时钟配置函数 (需要根据具体 MCU 实现)
void SystemClock_Config(void) {
// ... 配置系统时钟的代码
}

// 错误处理函数
void Error_Handler(void) {
while (1) {
// 错误指示 (例如快速闪烁 LED)
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_SET);
HAL_Delay(100);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_RESET);
HAL_Delay(100);
}
}

项目开发流程与实践验证

一个完整的嵌入式系统开发流程,需要经过以下几个关键阶段:

  1. 需求分析与系统设计: 如同我们前面所做的,详细分析产品需求,确定系统功能和性能指标,设计系统架构和模块划分。

  2. 硬件选型与原理图设计: 根据系统需求选择合适的 MCU、传感器、BMS 芯片等硬件器件,设计硬件原理图和 PCB 板。

  3. 软件开发与代码实现: 基于系统架构,分层编写代码,实现各个模块的功能。代码实现需要遵循良好的编码规范,注重模块化、可读性和可维护性。

  4. 单元测试: 针对每个软件模块进行单元测试,验证模块功能的正确性。可以使用单元测试框架 (例如 CUnit, CMocka) 来提高测试效率和覆盖率。

  5. 集成测试: 将各个模块集成起来进行测试,验证模块之间的协同工作是否正常。集成测试需要模拟实际运行环境,测试系统的整体功能和性能。

  6. 系统测试: 在实际硬件平台上进行系统测试,验证系统的功能、性能、稳定性、可靠性等指标是否满足需求。系统测试包括功能测试、性能测试、压力测试、可靠性测试、安全性测试等。

  7. 硬件在环测试 (HIL - Hardware-in-the-Loop): 使用 HIL 仿真器模拟实际硬件环境,对嵌入式软件进行测试。HIL 测试可以在软件开发的早期阶段发现硬件相关的问题,降低后期硬件测试的风险。

  8. 实际环境测试: 将产品部署到实际应用环境中进行测试,验证产品在真实环境下的性能和可靠性。

  9. 维护与升级: 在产品发布后,需要持续进行维护和升级,修复 bug,添加新功能,提升产品性能。对于嵌入式系统,远程升级 (OTA - Over-The-Air) 技术非常重要,可以方便地进行软件升级,降低维护成本。

实践验证的技术和方法

在这个项目中,我们采用了很多经过实践验证的技术和方法:

  • 分层架构: 提高了代码的模块化、可维护性和可扩展性,是嵌入式系统软件设计的常用架构。
  • 硬件抽象层 (HAL): 屏蔽了底层硬件差异,提高了代码的移植性,方便在不同硬件平台上复用代码。
  • 设备驱动层: 封装了硬件设备的操作细节,为上层软件提供了简洁易用的接口,降低了上层软件的开发复杂度。
  • 状态机: 对于复杂的控制逻辑,可以使用状态机来管理系统状态和事件处理,提高代码的可读性和可维护性 (虽然示例代码中没有显式使用状态机,但在 BMS 核心逻辑中可以引入状态机来管理不同的保护状态、均衡状态等)。
  • 定时器: 使用定时器来周期性地执行任务,例如数据采集、状态监控、均衡控制等,保证系统的实时性。
  • 中断: 对于需要快速响应的事件,可以使用中断机制,例如按键输入、外部事件触发等,提高系统的响应速度。
  • ADC: 使用 ADC 采集模拟信号,例如电压、电流、温度等,实现对物理世界的感知。
  • I2C/SPI/UART: 使用常用的通信协议与外设芯片 (例如 BMS 芯片) 进行通信,实现数据交换和控制。
  • 错误处理机制: 完善的错误处理机制是保证系统可靠性的关键。代码中需要考虑各种可能的错误情况,并进行相应的错误检测、错误报告和错误恢复。
  • 代码审查: 进行代码审查可以及早发现代码中的问题,提高代码质量。
  • 版本控制: 使用版本控制系统 (例如 Git) 管理代码,方便代码的版本管理、协作开发和回溯。
  • 持续集成/持续交付 (CI/CD): 可以引入 CI/CD 流程,自动化代码构建、测试和部署过程,提高开发效率和软件质量。

总结与展望

这款高颜值可视化可更换电池21700储能单元电池盒的嵌入式系统软件设计,采用了分层架构,模块化设计,并结合了多种实践验证的技术和方法,旨在构建一个可靠、高效、可扩展的系统平台。代码示例涵盖了 HAL 层、设备驱动层、BMS 核心逻辑层和应用层的基本框架,展示了核心功能的实现思路。

在实际项目中,还需要根据具体的硬件平台、BMS 芯片型号、功能需求等进行详细设计和代码实现。例如,BMS 均衡策略可以进一步优化,可以实现更精确的 SOC/SOH 估算,可以添加通信接口与上位机或其他设备进行数据交互和远程控制,可以考虑低功耗设计以延长电池续航时间等等。

希望这个详细的解答能够帮助你理解嵌入式系统软件设计的思路和方法,并为你的项目开发提供参考。如果还有其他问题,欢迎继续提问。

欢迎关注我的其它发布渠道