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(避免噪声)。

// 定时器初始化(简化)
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低边。注意:必须确保同一桥臂上下管不能同时导通,否则短路。

// 低边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引脚。

// 换相状态结构体
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 换相函数

// 设置换相状态
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)。使用定时器中断或延时实现。

// 全局变量
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控制低边,配合换相表即可驱动电机旋转。开环控制简单易行,适合入门学习,但实际应用中建议结合霍尔传感器或反电动势检测实现闭环,以提高可靠性和动态性能。希望本文能为你后续的电机控制开发打下坚实基础。