大家好,我是專注分享職業(yè)規(guī)劃/技術(shù)科普/智能生活有關(guān)原創(chuàng)文章的allen康哥。今天分享下關(guān)于用STM32設(shè)計BMS從控模塊的思路。
1??硬件設(shè)計思路
>電壓采集電路設(shè)計(精度±2mV)
精密分壓電路設(shè)計
采用0.1%精度的金屬膜電阻
分壓比計算:Vcell_max = 4.2V時,ADC輸入≤3.3V
典型取值:R1=100kΩ,R2=22kΩ(分壓比1:0.22)
低通濾波設(shè)計:RC時間常數(shù)τ=10ms(R=1kΩ,C=10μF)
選用零漂移運放AD8628
共模電壓抑制比>120dB
ADC配置要點
STM32F4內(nèi)置12位ADC
參考電壓使用外部2.5V基準(zhǔn)源(REF3025)
采樣周期配置為480周期(提高信噪比)
>被動均衡電路設(shè)計
// 均衡控制邏輯示例
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??軟件開發(fā)思路
>開發(fā)環(huán)境搭建
-
- CubeMX配置(時鐘樹/ADC/DMA)FreeRTOS任務(wù)劃分(500ms采集周期)
?>電壓采集核心代碼
// ADC DMA配置(8通道循環(huán)采樣)
#define CELL_NUM 8
volatile 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);
}
>軟件濾波算法
// 滑動平均濾波實現(xiàn)
#define FILTER_WINDOW 8
typedef 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;
}
閱讀全文