STM32F103驱动三相无刷电机:手把手教你用CubeMX和HAL库配置3PWM驱动(附完整源码)

张开发
2026/4/19 20:04:15 15 分钟阅读

分享文章

STM32F103驱动三相无刷电机:手把手教你用CubeMX和HAL库配置3PWM驱动(附完整源码)
STM32F103三相无刷电机驱动实战从CubeMX配置到SimpleFOC移植全解析在嵌入式开发领域无刷电机控制一直是极具挑战性的技术方向。对于刚接触STM32和电机控制的开发者来说如何快速搭建一个稳定可靠的三相PWM驱动系统往往是项目开发的第一道门槛。本文将基于STM32F103系列MCU结合CubeMX配置工具和HAL库详细讲解3PWM驱动无刷电机的完整实现流程包括硬件连接、定时器配置、SimpleFOC库移植等关键环节并提供可直接用于生产的完整代码方案。1. 硬件准备与系统架构1.1 硬件选型与连接开发三相无刷电机驱动系统需要以下核心硬件组件主控芯片STM32F103C8T6Blue Pill开发板驱动模块DRV8313或IR2104三相半桥驱动板无刷电机三相BLDC或PMSM电机KV值根据应用需求选择电源系统12-24V直流电源电流需满足电机额定需求硬件连接示意图如下信号线STM32引脚驱动板接口注意事项PWM Phase APA8PWM1建议使用TIM1_CH1PWM Phase BPA9PWM2建议使用TIM1_CH2PWM Phase CPA10PWM3建议使用TIM1_CH3Enable信号PB12EN可选用于安全使能电源正极-VCC12-24V需加滤波电容电源负极-GND确保共地提示实际接线时务必先断开电源使用万用表确认无短路后再上电测试。电机大电流线路应使用足够粗的导线避免因线路电阻导致压降过大。1.2 系统工作原理三相无刷电机的驱动核心是通过按特定顺序激活三相绕组产生旋转磁场。3PWM驱动模式下PWM生成STM32定时器产生三路中心对齐的PWM信号换相控制根据转子位置编码器或传感器反馈决定激活哪两相电流调节通过PWM占空比控制绕组电流大小保护机制过流检测、死区时间插入等确保系统安全// 典型的三相驱动信号时序 Phase A: [PWM]-----____-----____----- Phase B: ____-----____-----____----- Phase C: ____-----____-----[PWM]-----2. CubeMX工程配置2.1 定时器PWM配置打开CubeMX创建新工程选择对应STM32F103型号配置时钟树确保系统时钟达到72MHz定时器时钟源定时器TIM1配置ModePWM Generation CH1/CH2/CH3Prescaler0不分频Counter Period359920kHz PWM频率Pulse1800初始50%占空比Counter ModeCenter aligned mode 1CH PolarityHigh根据驱动芯片需求调整高级参数配置Dead Time建议50-100ns根据驱动芯片规格调整Break功能启用用于紧急停止自动重载预装载Enable2.2 GPIO与中断配置使能三相PWM对应GPIOPA8/PA9/PA10配置Enable引脚为输出模式PB12定时器中断配置使能TIM1_UP_IRQn中断设置合适的中断优先级// 生成的HAL库初始化代码片段 static void MX_TIM1_Init(void) { TIM_ClockConfigTypeDef sClockSourceConfig {0}; TIM_MasterConfigTypeDef sMasterConfig {0}; TIM_OC_InitTypeDef sConfigOC {0}; TIM_BreakDeadTimeConfigTypeDef sBreakDeadTimeConfig {0}; htim1.Instance TIM1; htim1.Init.Prescaler 0; htim1.Init.CounterMode TIM_COUNTERMODE_CENTERALIGNED1; htim1.Init.Period 3599; htim1.Init.ClockDivision TIM_CLOCKDIVISION_DIV1; htim1.Init.RepetitionCounter 0; htim1.Init.AutoReloadPreload TIM_AUTORELOAD_PRELOAD_ENABLE; // ... 其他配置代码 }3. SimpleFOC库移植与适配3.1 BLDCDriver3PWM类修改SimpleFOC库默认支持多种硬件平台需要针对STM32F103进行适配复制BLDCDriver3PWM.cpp和.h文件到项目目录主要修改内容// 修改后的BLDCDriver3PWM构造函数 BLDCDriver3PWM::BLDCDriver3PWM(int phA, int phB, int phC, int en) { // STM32硬件相关初始化 pwmA phA; pwmB phB; pwmC phC; enable_pin en; // 初始化默认参数 voltage_power_supply 12.0; // 根据实际电源设置 voltage_limit 12.0; pwm_frequency 20000; // 20kHz } // 修改PWM设置函数 void BLDCDriver3PWM::setPwm(float Ua, float Ub, float Uc) { // 电压限制 Ua _constrain(Ua, 0, voltage_limit); Ub _constrain(Ub, 0, voltage_limit); Uc _constrain(Uc, 0, voltage_limit); // 转换为占空比 float dc_a Ua / voltage_power_supply; float dc_b Ub / voltage_power_supply; float dc_c Uc / voltage_power_supply; // STM32 HAL库PWM设置 __HAL_TIM_SET_COMPARE(htim1, TIM_CHANNEL_1, dc_a * htim1.Init.Period); __HAL_TIM_SET_COMPARE(htim1, TIM_CHANNEL_2, dc_b * htim1.Init.Period); __HAL_TIM_SET_COMPARE(htim1, TIM_CHANNEL_3, dc_c * htim1.Init.Period); }3.2 硬件抽象层实现创建hardware_api.cpp实现STM32特定功能#include hardware_api.h #include tim.h // PWM初始化 void _configure3PWM(long pwm_frequency, const int pinA, const int pinB, const int pinC) { // STM32 CubeMX已配置定时器此处仅验证参数 if(htim1.Init.Prescaler ! 0 || htim1.Init.Period ! 3599) { // 错误处理 } } // 设置三相PWM占空比 void _writeDutyCycle3PWM(float dc_a, float dc_b, float dc_c, int pinA, int pinB, int pinC) { TIM1-CCR1 (uint32_t)(dc_a * TIM1-ARR); TIM1-CCR2 (uint32_t)(dc_b * TIM1-ARR); TIM1-CCR3 (uint32_t)(dc_c * TIM1-ARR); }4. 系统集成与调试4.1 主程序框架#include main.h #include BLDCDriver3PWM.h #include motor.h BLDCDriver3PWM driver BLDCDriver3PWM(PA8, PA9, PA10, PB12); BLDCMotor motor BLDCMotor(7); // 7极对数 void main() { // 硬件初始化 HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); MX_TIM1_Init(); // 电机驱动初始化 driver.voltage_power_supply 12.0; driver.init(); driver.enable(); // 电机参数配置 motor.voltage_limit 5.0; // 安全限制 motor.velocity_limit 100.0; // rad/s motor.linkDriver(driver); // 启动PWM HAL_TIM_PWM_Start(htim1, TIM_CHANNEL_1); HAL_TIM_PWM_Start(htim1, TIM_CHANNEL_2); HAL_TIM_PWM_Start(htim1, TIM_CHANNEL_3); while(1) { // 开环速度测试 motor.move(2.0); // 2V电压 HAL_Delay(10); } }4.2 常见问题排查PWM无输出检查定时器时钟是否使能验证GPIO复用功能配置确认HAL_TIM_PWM_Start已调用电机抖动不转检查电源电压是否足够验证三相接线顺序是否正确调整PWM死区时间电流过大降低电压限制值检查MOSFET或驱动芯片是否损坏确保电机没有机械堵转调试技巧使用示波器观察三相PWM波形确保频率正确20kHz占空比变化平滑死区时间有效中心对齐模式正确5. 进阶优化方向5.1 电流采样实现在中心对齐PWM模式下最佳电流采样时机是在PWM周期的中点void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) { if(htim htim1) { // 只在计数器上溢时采样PWM周期中点 static bool sample_phase true; if(sample_phase) { motor.currentA readCurrentADC(ADC_CHANNEL_1); motor.currentB readCurrentADC(ADC_CHANNEL_2); FOCAlgorithmUpdate(motor); // 更新FOC算法 } sample_phase !sample_phase; } }5.2 速度闭环控制集成编码器实现速度闭环配置正交编码器接口TIM2或TIM4添加速度估算算法实现PID控制器// 速度PID控制示例 void velocityPIDUpdate(BLDCMotor *motor) { float error motor-target_velocity - motor-shaft_velocity; motor-PID_velocity.integral error * motor-PID_velocity.Ts; // 积分限幅 motor-PID_velocity.integral _constrain(motor-PID_velocity.integral, -motor-PID_velocity.limit, motor-PID_velocity.limit); // PID计算 float output motor-PID_velocity.P * error motor-PID_velocity.I * motor-PID_velocity.integral motor-PID_velocity.D * (error - motor-PID_velocity.prev_error); output _constrain(output, -motor-voltage_limit, motor-voltage_limit); // 更新电机电压 motor-setVoltage(output); }实际项目中我们还需要考虑温度监测、故障保护、通信接口等功能模块。通过模块化设计可以构建一个稳定可靠的无刷电机驱动系统。

更多文章