STM32驱动无刷直流电机:原理图与驱动程序实现
一、核心结论
STM32驱动无刷直流电机(BLDC)的核心架构为:STM32微控制器(如F103、F407)通过高级定时器生成互补PWM信号,驱动三相桥逆变电路,结合霍尔传感器(或反电动势检测)实现转子位置检测,通过FOC(磁场定向控制)或六步换相法控制电机转速与扭矩。以下是完整的原理图设计、驱动程序实现及关键优化策略。
二、硬件原理图设计(核心模块)
无刷直流电机的驱动系统主要由STM32主控、三相桥逆变电路、霍尔传感器接口、电流采样电路、电源管理模块组成,以下是各模块的详细设计:
1. 三相桥逆变电路(核心功率级)
-
电路拓扑:采用三相全桥逆变电路(6个MOSFET/IGBT组成),分为上桥臂(UH、VH、WH)和下桥臂(UL、VL、WL),分别由STM32的高级定时器(如TIM1)的互补PWM通道驱动。
-
关键元件:
-
MOSFET:选择高开关频率、低导通电阻的器件(如IRFS3607,耐压100V、电流360A);
-
驱动芯片:采用IR2110S(半桥驱动),用于放大STM32的逻辑信号,驱动MOSFET的栅极,同时提供死区时间(防止上下桥臂直通);
-
自举电路:IR2110S的
VB引脚通过电容(如100nF)连接至VS,用于生成高端MOSFET的栅极驱动电压(需大于MOSFET的VGS(th),如10V)。
-
-
原理图细节:
-
上桥臂驱动:IR2110S的
HIN引脚连接STM32的PWM输出(如TIM1_CH1),LIN引脚接地; -
下桥臂驱动:IR2110S的
LIN引脚连接STM32的PWM输出(如TIM1_CH1N),HIN引脚接地; -
续流二极管:并联在MOSFET两端(如FR107),用于吸收电机绕组的反电动势,保护MOSFET。
-
2. 霍尔传感器接口(位置检测)
-
电路拓扑:霍尔传感器(如A1120,开关型)安装在电机转子附近,输出三路信号(H1、H2、H3),连接至STM32的通用定时器(如TIM2)的输入捕获通道。
-
关键设计:
-
霍尔电源:采用5V稳压电源(如LM1117-5.0),为霍尔传感器供电;
-
信号调理:霍尔输出信号通过RC滤波(如1kΩ电阻+100nF电容),去除高频噪声;
-
定时器配置:STM32的TIM2设置为输入捕获模式,捕获霍尔信号的上升沿,用于计算转子位置(六步换相法)。
-
3. 电流采样电路(闭环控制)
-
电路拓扑:采用单电阻采样法(在直流母线的负极串联一个小电阻,如0.01Ω/2W),通过运放(如LM358)放大采样电压,连接至STM32的ADC通道(如PA0)。
-
关键设计:
-
采样电阻:选择低电感、高精度的康铜丝电阻,减少高频噪声;
-
运放放大:采用差分放大电路(增益10倍),将采样电压放大至ADC的输入范围(0-3.3V);
-
滤波:在运放输出端并联100nF电容,去除高频噪声。
-
4. 电源管理模块
-
输入电源:采用24V直流电源(适配大多数BLDC电机),通过LM2596降压至12V(给MOSFET驱动电路供电),再通过AMS1117-3.3降压至3.3V(给STM32供电)。
-
保护电路:
-
输入保险丝:串联在24V输入端(如5A),防止过流损坏电路;
-
TVS管:并联在24V输入端(如P6KE15CA),吸收浪涌电压;
-
去耦电容:在STM32的VDD引脚附近并联100nF陶瓷电容(高频去耦)和10μF电解电容(低频去耦)。
-
三、驱动程序实现(核心代码与逻辑)
STM32驱动BLDC的软件实现主要包括初始化配置(HAL库)、PWM生成、霍尔信号处理、FOC控制算法、故障保护,以下是基于STM32F103的代码实现(使用HAL库):
1. 初始化配置(时钟、GPIO、定时器、ADC)
#include "stm32f10x.h"
#include "stm32f10x_hal.h"
// 定义引脚
#define TIM1_CH1_PIN GPIO_PIN_8 // PA8(TIM1_CH1)
#define TIM1_CH1_PORT GPIOA
#define HALL_H1_PIN GPIO_PIN_0 // PA0(HALL_H1)
#define HALL_H1_PORT GPIOA
// 全局变量
TIM_HandleTypeDef htim1;
ADC_HandleTypeDef hadc1;
volatile uint8_t hall_state = 0; // 霍尔状态
int main(void) {
HAL_Init();
SystemClock_Config(); // 系统时钟配置(72MHz)
MX_GPIO_Init(); // GPIO初始化
MX_TIM1_Init(); // TIM1初始化(PWM)
MX_ADC1_Init(); // ADC1初始化(电流采样)
HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1); // 启动TIM1 PWM
HAL_ADC_Start_IT(&hadc1, ADC1_CHANNEL_0); // 启动ADC中断(电流采样)
while (1) {
// 主循环:处理FOC控制、霍尔信号
}
}
// TIM1初始化(PWM)
void MX_TIM1_Init(void) {
TIM_OC_InitTypeDef TIM_OC_InitStruct = {0};
TIM_MasterConfigTypeDef TIM_MasterConfigStruct = {0};
htim1.Instance = TIM1;
htim1.Init.Prescaler = 71; // 预分频71,时钟1MHz(72MHz/72)
htim1.Init.CounterMode = TIM_COUNTERMODE_UP; // 向上计数
htim1.Init.Period = 1999; // 自动重载值1999,PWM频率5kHz(1MHz/2000)
htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim1.Init.RepetitionCounter = 0;
HAL_TIM_PWM_Init(&htim1);
// 配置TIM1_CH1(PWM输出)
TIM_OC_InitStruct.OCMode = TIM_OCMODE_PWM1;
TIM_OC_InitStruct.Pulse = 1000; // 占空比50%(1000/2000)
TIM_OC_InitStruct.OCPolarity = TIM_OCPOLARITY_HIGH;
TIM_OC_InitStruct.OCFastMode = TIM_OCFAST_DISABLE;
HAL_TIM_PWM_ConfigChannel(&htim1, &TIM_OC_InitStruct, TIM_CHANNEL_1);
// 配置死区时间(1.5μs)
TIM_BDTRInitTypeDef TIM_BDTR_InitStruct = {0};
TIM_BDTR_InitStruct.DeadTime = 0x0F; // 死区时间1.5μs(0.1μs/单位)
TIM_BDTR_InitStruct.LockLevel = TIM_LOCKLEVEL_OFF;
TIM_BDTR_InitStruct.DeadTimeCompensation = TIM_DEADTIMECOMPENSATION_DISABLE;
HAL_TIMEx_ConfigDeadTime(&htim1, &TIM_BDTR_InitStruct);
// 配置主从模式(TIM1作为主定时器)
TIM_MasterConfigStruct.MasterOutputTrigger = TIM_TRGO_UPDATE;
TIM_MasterConfigStruct.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
HAL_TIMEx_MasterConfigSynchronization(&htim1, &TIM_MasterConfigStruct);
}
// ADC1初始化(电流采样)
void MX_ADC1_Init(void) {
ADC_ChannelConfTypeDef sConfig = {0};
hadc1.Instance = ADC1;
hadc1.Init.ScanConvMode = ADC_SCAN_DISABLE;
hadc1.Init.ContinuousConvMode = ADC_CONTINUOUS_CONV_ENABLE;
hadc1.Init.DiscontinuousConvMode = ADC_DISCONTINUOUS_CONV_DISABLE;
hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc1.Init.NbrOfConversion = 1;
HAL_ADC_Init(&hadc1);
// 配置ADC通道0(PA0)
sConfig.Channel = ADC_CHANNEL_0;
sConfig.Rank = ADC_REGULAR_RANK_1;
sConfig.SamplingTime = ADC_SAMPLETIME_55CYCLES_5;
HAL_ADC_ConfigChannel(&hadc1, &sConfig);
}
// GPIO初始化
void MX_GPIO_Init(void) {
GPIO_InitTypeDef GPIO_InitStruct = {0};
// 使能GPIO时钟
__HAL_RCC_GPIOA_CLK_ENABLE();
// TIM1_CH1(PA8)配置为复用推挽输出
GPIO_InitStruct.Pin = TIM1_CH1_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(TIM1_CH1_PORT, &GPIO_InitStruct);
// HALL_H1(PA0)配置为浮空输入
GPIO_InitStruct.Pin = HALL_H1_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(HALL_H1_PORT, &GPIO_InitStruct);
}
2. 霍尔信号处理(获取转子位置)
霍尔传感器输出三路信号(H1、H2、H3),通过定时器输入捕获获取霍尔状态,判断转子位置(六步换相法)。
// 霍尔状态解码(H1、H2、H3组合)
uint8_t Get_Hall_State(void) {
uint8_t h1 = HAL_GPIO_ReadPin(HALL_H1_PORT, HALL_H1_PIN);
uint8_t h2 = HAL_GPIO_ReadPin(HALL_H2_PORT, HALL_H2_PIN);
uint8_t h3 = HAL_GPIO_ReadPin(HALL_H3_PORT, HALL_H3_PIN);
return (h1 << 2) | (h2 << 1) | h3; // 组合为3位状态(0-7)
}
// TIM2中断服务函数(霍尔信号捕获)
void TIM2_IRQHandler(void) {
HAL_TIM_IRQHandler(&htim2);
}
// TIM2输入捕获回调函数
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim) {
if (htim->Instance == TIM2) {
hall_state = Get_Hall_State(); // 获取霍尔状态
// 根据霍尔状态判断换相(六步换相法)
switch (hall_state) {
case 0b001: // H1=1, H2=0, H3=0 → 换相到状态1
HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1); // 开启U相上桥臂
HAL_TIM_PWM_Stop(&htim1, TIM_CHANNEL_2); // 关闭V相上桥臂
break;
case 0b011: // H1=1, H2=1, H3=0 → 换相到状态2
HAL_TIM_PWM_Stop(&htim1, TIM_CHANNEL_1); // 关闭U相上桥臂
HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_2); // 开启V相上桥臂
break;
// 其他状态类似处理
default:
break;
}
}
}
3. FOC控制算法(磁场定向控制)
FOC控制是BLDC电机的高性能控制方法,通过Clarke变换(3相→2相)、Park变换(静止→旋转)、SVPWM生成(空间矢量脉宽调制)实现转矩与速度的精确控制。
// Clarke变换(3相→2相)
typedef struct {
float a; // α轴电流
float b; // β轴电流
} Clarke_t;
Clarke_t Clarke_Transform(float ia, float ib, float ic) {
Clarke_t clarke;
clarke.a = ia;
clarke.b = (ib - ic) / sqrt(3); // β轴电流计算公式
return clarke;
}
// Park变换(静止→旋转)
typedef struct {
float d; // d轴电流(励磁分量)
float q; // q轴电流(转矩分量)
} Park_t;
Park_t Park_Transform(Clarke_t clarke, float theta) {
Park_t park;
park.d = clarke.a * cos(theta) + clarke.b * sin(theta); // d轴电流计算公式
park.q = -clarke.a * sin(theta) + clarke.b * cos(theta); // q轴电流计算公式
return park;
}
// SVPWM生成(空间矢量脉宽调制)
void SVPWM_Generate(Park_t park, float vdc) {
float ud = park.d; // d轴电压参考
float uq = park.q; // q轴电压参考
// 反Park变换(旋转→静止)
float ua = ud;
float ub = -ud * sin(theta) + uq * cos(theta);
float uc = -ud * cos(theta) - uq * sin(theta);
// SVPWM占空比计算(基于ua、ub、uc)
float ta = (ua + 1) / 2 * vdc; // TA占空比
float tb = (ub + 1) / 2 * vdc; // TB占空比
float tc = (uc + 1) / 2 * vdc; // TC占空比
// 设置PWM占空比(TIM1_CH1、TIM1_CH2、TIM1_CH3)
TIM1->CCR1 = ta * (TIM1->ARR + 1);
TIM1->CCR2 = tb * (TIM1->ARR + 1);
TIM1->CCR3 = tc * (TIM1->ARR + 1);
}
4. 故障保护(过流、过压、欠压)
过流保护:通过ADC采样电流,当电流超过阈值(如5A)时,关闭PWM输出,点亮故障LED。
// ADC中断服务函数(电流采样)
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc) {
if (hadc->Instance == ADC1) {
float current = (HAL_ADC_GetValue(hadc) * 3.3 / 4096) * (100 / 0.01); // 电流计算(0-100A)
if (current > 5.0) { // 过流阈值5A
HAL_TIM_PWM_Stop(&htim1, TIM_CHANNEL_1); // 关闭PWM
HAL_GPIO_WritePin(LED_PORT, LED_PIN, GPIO_PIN_SET); // 点亮故障LED
}
}
}
参考代码 STM32驱动无刷直流电机包括原理图和驱动程序 www.youwenfan.com/contentcnp/112793.html
四、关键优化策略
-
PWM频率优化:选择合适的PWM频率(如5kHz),避免过高频率导致MOSFET开关损耗增加,过低频率导致电流纹波增大。
-
死区时间优化:根据MOSFET的
VGS(th)(如10V)和驱动电路的延迟,设置合适的死区时间(如1.5μs),防止上下桥臂直通。 -
电流采样优化:采用差分放大电路和RC滤波,减少电流采样的噪声,提高控制精度。
-
FOC参数优化:调整PI控制器的参数(如
Kp=0.1,Ki=0.05),优化转矩响应和稳态误差。
五、调试与验证
-
硬件调试:使用万用表测量电源电压(如12V、3.3V)是否正常,使用示波器测量PWM波形(如5kHz、50%占空比)是否正确。
-
软件调试:使用Keil MDK的Debug功能,查看霍尔状态(如
hall_state)、电流采样值(如current)是否正确。 -
性能测试:测量电机的转速(如用编码器)、转矩(如用扭矩传感器),验证FOC控制的精度(如转速误差<1%,转矩误差<5%)。
六、总结
STM32驱动BLDC电机的核心是硬件电路的正确设计(三相桥、驱动芯片、霍尔传感器)和软件算法的优化(FOC、霍尔处理、故障保护)。通过本文的原理图和代码实现,开发者可以快速搭建BLDC电机驱动系统,并根据实际需求调整参数(如PWM频率、PI参数),实现高性能的电机控制。

浙公网安备 33010602011771号