【免费开源】STM32有感无刷直流电机BLDC六步换相驱动程序完整工程实战分享一、项目背景无刷直流电机BLDC凭借效率高、噪声低、寿命长的优势已经广泛应用于无人机、电动工具、电动滑板、风机、扫地机器人等领域。BLDC 控制方式主要分为有感带霍尔传感器和无感反电势检测/FOC两类。本项目STM32有感无刷直流电机驱动程序实现的是经典的六步换相方波控制依靠三个霍尔传感器实时反馈转子位置配合 PWM 调速能够稳定地驱动 BLDC 在 0~10000rpm 范围内运行。主要特性基于 STM32F103C8T6也可移植到 F4/G4定时器 TIM1 输出 6 路互补 PWM霍尔信号通过 EXTI 中断捕获换相延时 5us支持加减速曲线梯形加减速避免堵转提供电流采样接口ADC 比较器可实现限流保护通过串口或 PWM 输入指令调速便于上位机或遥控接入。二、六步换相原理与项目流程图BLDC 三相绕组按 120° 电角度依次通电结合三个霍尔传感器HA、HB、HC相隔 120°构成 6 种状态对应 6 个换相区间。每次霍尔状态翻转MCU 立刻切换 PWM 通道输出使转子持续向同一方向旋转。否是否是STM32 上电GPIO/TIM1/EXTI/ADC 初始化读取霍尔输入 HA/HB/HC计算霍尔状态 1~6查表得到当前换相方案例U V- W关设置 TIM1_CCER 开关相应通道设置占空比 用户给定值霍尔信号边沿?ADC 采样母线电流电流 阈值?关闭 PWM 输出报错EXTI 中断触发重新读取霍尔状态更新换相表索引累加换相计数器计算转速等待用户复位三、硬件结构信号STM32 引脚备注TIM1_CH1PA8U 相高侧 PWMTIM1_CH1NPB13U 相低侧 PWM互补TIM1_CH2PA9V 相高侧 PWMTIM1_CH2NPB14V 相低侧 PWMTIM1_CH3PA10W 相高侧 PWMTIM1_CH3NPB15W 相低侧 PWMTIM1_BKINPB12刹车输入过流时拉低HA/HB/HCPA0/PA1/PA2霍尔输入配置 EXTI 中断ADC1_CH4PA4母线电流采样电源端推荐使用三相全桥栅极驱动器如 IR2103 或 EG2103低侧串联 0.01Ω 采样电阻接到运放放大后输入 ADC。四、核心代码4.1 bldc.h#ifndef__BLDC_H__#define__BLDC_H__#includestm32f1xx_hal.hvoidBLDC_Init(TIM_HandleTypeDef*htim1);voidBLDC_Start(void);voidBLDC_Stop(void);voidBLDC_SetDuty(uint16_tduty);/* 0~999 */voidBLDC_HallIRQ(void);/* 在 EXTI 中调用 */floatBLDC_GetSpeedRPM(void);#endif4.2 bldc.c#includebldc.hstaticTIM_HandleTypeDef*s_htim;staticvolatileuint16_ts_duty;staticvolatileuint32_ts_hall_cnt;staticvolatileuint32_ts_last_tick;staticvolatilefloats_rpm;/* 霍尔状态 - (高侧通道, 低侧通道)用位掩码表示 */staticconstuint8_thall_table[8][2]{/* 0:non */{0,0},/* 1:H_A */{0x01,0x04},/* U , W- *//* 2:H_B */{0x04,0x02},/* W , V- *//* 3:HAB */{0x01,0x02},/* U , V- *//* 4:H_C */{0x02,0x01},/* V , U- *//* 5:HAC */{0x02,0x04},/* V , W- *//* 6:HBC */{0x04,0x01},/* W , U- *//* 7:non */{0,0}};staticuint8_tReadHall(void){uint8_ts0;if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0))s|0x01;if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_1))s|0x02;if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_2))s|0x04;returns;}staticvoidCommutate(uint8_thall){uint8_thihall_table[hall][0];uint8_tlohall_table[hall][1];/* 关闭所有通道 */__HAL_TIM_DISABLE_OCxPRELOAD(s_htim,TIM_CHANNEL_1);HAL_TIMEx_PWMN_Stop(s_htim,TIM_CHANNEL_1);HAL_TIMEx_PWMN_Stop(s_htim,TIM_CHANNEL_2);HAL_TIMEx_PWMN_Stop(s_htim,TIM_CHANNEL_3);HAL_TIM_PWM_Stop(s_htim,TIM_CHANNEL_1);HAL_TIM_PWM_Stop(s_htim,TIM_CHANNEL_2);HAL_TIM_PWM_Stop(s_htim,TIM_CHANNEL_3);/* 打开高侧 PWM 调制 */if(hi0x01){__HAL_TIM_SET_COMPARE(s_htim,TIM_CHANNEL_1,s_duty);HAL_TIM_PWM_Start(s_htim,TIM_CHANNEL_1);}if(hi0x02){__HAL_TIM_SET_COMPARE(s_htim,TIM_CHANNEL_2,s_duty);HAL_TIM_PWM_Start(s_htim,TIM_CHANNEL_2);}if(hi0x04){__HAL_TIM_SET_COMPARE(s_htim,TIM_CHANNEL_3,s_duty);HAL_TIM_PWM_Start(s_htim,TIM_CHANNEL_3);}/* 打开低侧常通 (用 PWMN 100% 占空) */if(lo0x01){__HAL_TIM_SET_COMPARE(s_htim,TIM_CHANNEL_1,1000);HAL_TIMEx_PWMN_Start(s_htim,TIM_CHANNEL_1);}if(lo0x02){__HAL_TIM_SET_COMPARE(s_htim,TIM_CHANNEL_2,1000);HAL_TIMEx_PWMN_Start(s_htim,TIM_CHANNEL_2);}if(lo0x04){__HAL_TIM_SET_COMPARE(s_htim,TIM_CHANNEL_3,1000);HAL_TIMEx_PWMN_Start(s_htim,TIM_CHANNEL_3);}}voidBLDC_Init(TIM_HandleTypeDef*htim1){s_htimhtim1;s_duty0;s_hall_cnt0;s_last_tickHAL_GetTick();}voidBLDC_Start(void){Commutate(ReadHall());}voidBLDC_Stop(void){s_duty0;Commutate(0);}voidBLDC_SetDuty(uint16_tduty){if(duty1000)duty1000;s_dutyduty;}voidBLDC_HallIRQ(void){s_hall_cnt;Commutate(ReadHall());/* 每 100ms 计算一次转速6 次霍尔 1 个电气周期 */uint32_tnowHAL_GetTick();if(now-s_last_tick100){floatpulses(float)s_hall_cnt;floatseconds(now-s_last_tick)/1000.0f;s_rpm(pulses/6.0f/4.0f)/seconds*60.0f;/* 假设 4 对极 */s_hall_cnt0;s_last_ticknow;}}floatBLDC_GetSpeedRPM(void){returns_rpm;}4.3 主程序与 EXTI 回调externTIM_HandleTypeDef htim1;intmain(void){HAL_Init();SystemClock_Config();MX_GPIO_Init();MX_TIM1_Init();MX_USART1_UART_Init();BLDC_Init(htim1);BLDC_Start();uint16_tduty0;while(1){/* 梯形加速每 50ms 增加 10 */if(duty600)duty10;BLDC_SetDuty(duty);HAL_Delay(50);}}voidHAL_GPIO_EXTI_Callback(uint16_tpin){if(pinGPIO_PIN_0||pinGPIO_PIN_1||pinGPIO_PIN_2){BLDC_HallIRQ();}}五、关键技术点5.1 PWM 互补输出 死区TIM1 是 STM32 的高级定时器专为电机控制设计。配置时把BDTR.DTG设置为0x40左右约 1us 死区时间可以防止上下管直通烧毁。5.2 霍尔状态查表把所有 6 种霍尔组合映射到具体的换相方案可以使代码极其简洁且换相延时低至几个 us。如果电机反向旋转只需把hall_table[]中的高低侧互换即可。5.3 限流保护通过BKIN引脚连接到电流比较器输出。当电流超阈值时TIM1 立即关闭所有 PWM 通道并触发HAL_TIM_BreakCallback()软件可以记录故障日志。5.4 速度闭环本工程默认是开环调速直接给定占空比。如果需要闭环可以在 100ms 周期里执行errtarget_rpm-BLDC_GetSpeedRPM();dutyKp*errKi*integral_err;BLDC_SetDuty(duty);六、调试踩坑霍尔接线错乱很多电机的霍尔顺序不一样启动后转子抖动不前进就需要调换 hall_table死区太小会导致上下管直通电源瞬间被拉低PWM 频率建议 16~20kHz避开音频范围否则电机会发出吱吱声EXTI 触发模式必须配置为双边沿触发否则只能识别 3 个换相点电流采样时机要在 PWM 上桥导通中段进行采样避免开关噪声。七、扩展应用接入 PWM 输入捕获让航模遥控器直接控制电调升级到FOC 矢量控制用 STM32G4 STM32MotorControl SDK实现更平稳的调速配合 OLED 显示屏实时显示转速、电流、占空比制作电动滑板控制器、自平衡车、扫地机器人吸力电机等。八、总结本项目通过完整的 PWM、EXTI、ADC、状态机协作构建了一个稳定可靠的有感 BLDC 方波控制器代码不到 400 行却涵盖了无刷电机驱动的全部关键要点。它既可作为初学者理解 BLDC 工作原理的入门工程也可作为产品级嵌入式电机控制的代码骨架。完整工程已开源在压缩包中欢迎大家下载、使用、改进一起把用代码让电机转起来这件事做到极致。