• 正文
  • 相关推荐
申请入驻 产业图谱

用STM32设计BMS从控模块手把手教你

03/04 12:00
1497
加入交流群
扫码加入
获取工程师必备礼包
参与热点资讯讨论

 

大家好,我是专注分享职业规划/技术科普/智能生活有关原创文章的allen康哥。今天分享下关于用STM32设计BMS从控模块的思路。

1️⃣硬件设计思路

>电压采集电路设计(精度±2mV)

精密分压电路设计

采用0.1%精度的金属膜电阻

分压比计算:Vcell_max = 4.2V时,ADC输入≤3.3V

典型取值:R1=100kΩ,R2=22kΩ(分压比1:0.22)

低通滤波设计:RC时间常数τ=10ms(R=1kΩ,C=10μF)

运放缓冲电路

选用零漂移运放AD8628

配置电压跟随器消除阻抗影响

共模电压抑制比>120dB

ADC配置要点

STM32F4内置12位ADC

参考电压使用外部2.5V基准源(REF3025)

采样周期配置为480周期(提高信噪比

>被动均衡电路设计
// 均衡控制逻辑示例typedef struct {  uint8_t cell_num;  uint16_t balance_threshold;  GPIO_TypeDef* port;  uint16_t pin;} BalanceChannel;
void balance_control(BalanceChannel* ch, float cell_voltage) {  if (cell_voltage > ch->balance_threshold) {    HAL_GPIO_WritePin(ch->port, ch->pin, GPIO_PIN_SET);  } else {    HAL_GPIO_WritePin(ch->port, ch->pin, GPIO_PIN_RESET);  }}

2️⃣软件开发思路

>开发环境搭建

    • CubeMX配置(时钟树/ADC/DMA)FreeRTOS任务划分(500ms采集周期)
 >电压采集核心代码
// ADC DMA配置(8通道循环采样)#define CELL_NUM 8volatile uint16_t adc_buffer[CELL_NUM];
void ADC_Init() {  hadc1.Instance = ADC1;  hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4;  hadc1.Init.Resolution = ADC_RESOLUTION_12B;  hadc1.Init.ScanConvMode = ENABLE;  hadc1.Init.ContinuousConvMode = ENABLE;  hadc1.Init.DiscontinuousConvMode = DISABLE;  hadc1.Init.NbrOfDiscConversion = 0;  hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;  hadc1.Init.DMAContinuousRequests = ENABLE;  HAL_ADC_Init(&hadc1);
  ADC_ChannelConfTypeDef sConfig = {0};  for(int i=0; i<CELL_NUM; i++) {    sConfig.Channel = ADC_CHANNEL_0 + i;    sConfig.Rank = i+1;    sConfig.SamplingTime = ADC_SAMPLETIME_480CYCLES;    HAL_ADC_ConfigChannel(&hadc1, &sConfig);  }  HAL_ADC_Start_DMA(&hadc1, (uint32_t*)adc_buffer, CELL_NUM);}

>软件滤波算法

// 滑动平均滤波实现#define FILTER_WINDOW 8typedef struct {  float buffer[FILTER_WINDOW];  uint8_t index;} MovingAverage;
float filter_voltage(MovingAverage* filter, float new_val) {  filter->buffer[filter->index] = new_val;  filter->index = (filter->index + 1) % FILTER_WINDOW;    float sum = 0;  for(int i=0; i<FILTER_WINDOW; i++) {    sum += filter->buffer[i];  }  return sum / FILTER_WINDOW;}

 

相关推荐