## 1. 为什么需要六步换相? 无刷直流电机(BLDC)的转子是永磁体,定子绕组为三相(A、B、C)。与有刷电机不同,BLDC必须通过电子换相来改变定子磁场方向,从而驱动转子连续旋转。六步换相(Trapezoidal Control)是最基础的控制方式,每60°电角度切换一次导通状态,一个电气周期内完成6次换相。其优点是控制简单、成本低,适合对噪音和扭矩波动要求不高的场景。 ## 2. 六步换相原理 ### 2.1 电机模型与反电动势 BLDC的定子绕组通常为星形连接,反电动势(Back-EMF)呈梯形波。六步换相的关键是:在任意时刻,只有两相导通(一相高边、一相低边),第三相悬空。通过检测悬空相的反电动势过零点,可以获取转子位置(闭环),但开环控制则直接按固定顺序换相,无需传感器。 ### 2.2 换相顺序表 以A、B、C三相为例,定义高边为H,低边为L,悬空为Z。六步换相顺序如下(电角度0°~360°): | 步骤 | 导通相(高边→低边) | 悬空相 | |------|---------------------|--------| | 1 | A→B | C | | 2 | A→C | B | | 3 | B→C | A | | 4 | B→A | C | | 5 | C→A | B | | 6 | C→B | A | 注意:换相顺序与电机旋转方向相关,若反转则逆序执行。 ### 2.3 PWM调制策略 开环控制中,通常采用上桥臂PWM、下桥臂恒通(或反之)的方式。例如步骤1中,A相上桥臂PWM,B相下桥臂常开,C相悬空。PWM占空比决定平均电压,从而控制转速。常见调制方式有: - **ON-PWM**:高边PWM,低边常通,简单但开关损耗不均。 - **PWM-ON**:高边常通,低边PWM,适用于低压大电流。 - **互补PWM**:上下桥臂互补,带死区,适合正弦波驱动,但六步控制中较少用。 本文采用**高边PWM,低边恒通**,便于实现。 ## 3. STM32硬件配置 ### 3.1 硬件资源 - MCU:STM32F103C8T6(或其他系列) - 电机驱动:三相全桥(如IR2104+MOSFET) - 定时器:TIM1(高级定时器,产生6路PWM) - GPIO:用于控制换相逻辑(或直接使用PWM通道) ### 3.2 定时器配置 TIM1可产生6路互补PWM(CH1/CH1N, CH2/CH2N, CH3/CH3N),但六步控制中同一时刻只有两相导通,因此我们只需使用3个PWM通道(高边),低边用GPIO控制。配置TIM1为中央对齐模式或边沿对齐模式,频率20kHz(避免噪声)。 ```c // 定时器初始化(简化) void TIM1_PWM_Init(uint16_t arr, uint16_t psc) { GPIO_InitTypeDef GPIO_InitStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_OCInitTypeDef TIM_OCInitStructure; // 使能时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1 | RCC_APB2Periph_GPIOA, ENABLE); // 配置PA8, PA9, PA10为复用推挽输出(TIM1_CH1, CH2, CH3) GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); // 定时器基础配置 TIM_TimeBaseStructure.TIM_Period = arr; TIM_TimeBaseStructure.TIM_Prescaler = psc; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure); // PWM模式配置 TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = 0; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OC1Init(TIM1, &TIM_OCInitStructure); TIM_OC2Init(TIM1, &TIM_OCInitStructure); TIM_OC3Init(TIM1, &TIM_OCInitStructure); // 使能MOE(主输出使能) TIM_CtrlPWMOutputs(TIM1, ENABLE); TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable); TIM_OC2PreloadConfig(TIM1, TIM_OCPreload_Enable); TIM_OC3PreloadConfig(TIM1, TIM_OCPreload_Enable); TIM_ARRPreloadConfig(TIM1, ENABLE); TIM_Cmd(TIM1, ENABLE); } ``` ### 3.3 低边控制GPIO 低边MOSFET用普通GPIO控制,例如PB0, PB1, PB2分别对应A、B、C低边。注意:必须确保同一桥臂上下管不能同时导通,否则短路。 ```c // 低边GPIO初始化 void LowSide_GPIO_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStructure); } ``` ## 4. 六步换相代码实现 ### 4.1 换相状态表 定义换相状态结构体,包含高边PWM通道、低边GPIO引脚。 ```c // 换相状态结构体 typedef struct { uint8_t high_side_ch; // 高边PWM通道:1,2,3 uint16_t low_side_pin; // 低边GPIO引脚:GPIO_Pin_0/1/2 } Commutation_State; // 六步换相表(顺序:A-B, A-C, B-C, B-A, C-A, C-B) const Commutation_State comm_table[6] = { {1, GPIO_Pin_1}, // A高,B低 {1, GPIO_Pin_2}, // A高,C低 {2, GPIO_Pin_2}, // B高,C低 {2, GPIO_Pin_0}, // B高,A低 {3, GPIO_Pin_0}, // C高,A低 {3, GPIO_Pin_1} // C高,B低 }; ``` ### 4.2 换相函数 ```c // 设置换相状态 void Set_Commutation(uint8_t step) { // 关闭所有低边 GPIO_ResetBits(GPIOB, GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2); // 关闭所有高边PWM TIM_SetCompare1(TIM1, 0); TIM_SetCompare2(TIM1, 0); TIM_SetCompare3(TIM1, 0); // 设置当前状态 uint8_t ch = comm_table[step].high_side_ch; uint16_t low_pin = comm_table[step].low_side_pin; // 使能对应高边PWM(占空比由全局变量duty决定) if (ch == 1) TIM_SetCompare1(TIM1, duty); else if (ch == 2) TIM_SetCompare2(TIM1, duty); else if (ch == 3) TIM_SetCompare3(TIM1, duty); // 使能低边 GPIO_SetBits(GPIOB, low_pin); } ``` ### 4.3 主循环与换相定时 开环控制中,换相时间由转速决定。若目标电转速为RPM,则电气频率f = RPM * 极对数 / 60,换相周期T = 1 / (6 * f)。使用定时器中断或延时实现。 ```c // 全局变量 volatile uint16_t duty = 500; // 占空比0-1000 volatile uint8_t step = 0; // 定时器中断服务函数(假设TIM2用于换相定时) void TIM2_IRQHandler(void) { if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET) { TIM_ClearITPendingBit(TIM2, TIM_IT_Update); // 换相 Set_Commutation(step); step = (step + 1) % 6; } } // 主函数示例 int main(void) { // 初始化系统、GPIO、定时器等 SystemInit(); TIM1_PWM_Init(999, 71); // 72MHz/(72*1000)=1kHz? 实际20kHz需调整 LowSide_GPIO_Init(); // 配置TIM2为换相定时器,例如1ms中断(对应电转速1000rpm,极对数为1) // 计算:换相周期 = 1/(6*1000/60)=10ms,但实际需根据极对数调整 // 此处简化,使用固定1ms TIM2_Init(999, 71); // 1ms中断 while(1) { // 可调节占空比或转速 // 例如:duty = 500; // 50%占空比 } } ``` 注意:上述代码中TIM2初始化未给出,需根据实际需求配置。换相时间必须精确,否则电机可能失步。 ## 5. 注意事项 - **死区时间**:虽然六步控制中同一桥臂上下管不会同时导通,但为了安全,建议在PWM输出中加入死区(TIM1的BDTR寄存器),防止MOSFET开关延迟导致直通。 - **电流限制**:启动时电流可能很大,应设置软启动(逐渐增加占空比)或硬件限流。 - **换相时机**:开环控制下,换相频率必须与电机转速匹配。若负载变化导致转速下降,可能失步,因此开环仅适用于轻载或恒速场景。 - **反电动势检测**:若要实现闭环,可在悬空相上检测过零点,但需要额外的比较器电路或ADC采样。 - **PWM频率**:推荐20kHz以上,避免 audible noise。 - **电源去耦**:在电机电源端加足够容量的电解电容和陶瓷电容,抑制反电动势尖峰。 ## 6. 总结 本文详细介绍了基于STM32的BLDC六步换相开环控制,从原理到代码实现。通过定时器产生PWM,GPIO控制低边,配合换相表即可驱动电机旋转。开环控制简单易行,适合入门学习,但实际应用中建议结合霍尔传感器或反电动势检测实现闭环,以提高可靠性和动态性能。希望本文能为你后续的电机控制开发打下坚实基础。