问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

STM32F4采用6步法控制直流无刷电机

创作时间:
作者:
@小白创作中心

STM32F4采用6步法控制直流无刷电机

引用
CSDN
1.
https://blog.csdn.net/sinat_36568888/article/details/143905037

本文详细介绍了如何使用STM32单片机控制直流无刷电机。从6步控制原理开始,逐步讲解了半桥电路控制、状态切换表、正反转控制以及转速调整方法。最后,文章提供了具体的STM32程序设计,包括状态切换函数、状态获取函数和状态控制函数的代码实现。

前言

第一篇中用最通俗易懂的方式讲解了bldc电机的原理,以及最基本的6步控制原理,本篇将介绍怎么使用stm32单片机来实现6步法控制直流无刷电机。

6步法控制顺序

依然以1对极电机进行讲解,将第一篇中的霍尔反馈的状态按照2进制进行转换,比如在0°是ABC反馈值为110 对应十进制6,其他状态依次类推,可以得到6步状态对应电流变换表:

电角度
状态
电流方向
0
6
VW
60
2
UW
120
3
UV
180
1
WV
240
5
WU
300
4
VU

在控制的时候要根据当前的状态来改变定子线圈电流的方向。一般是采用3个半桥电路控制,如下图。

每个半桥由上半桥和下半桥两个mos管控制,上半桥记为+,下半桥记为-。需要改变线圈电流的方向,只需要控制对应的MOS管导通和关闭。比如AB(电流从A流向B),需要打开A+,记为状态ON,关闭A-,记为状态OFF,关闭B+,打开B-,C+和C-均保持关闭。要使电流反向BA,此时需要A+ OFF,A- ON,B+ ON,B- OFF,C+ OFF,C- OFF。

注意,A+和A-必需要互斥,同一时刻二者只能有一个导通,一个关闭。如果两个同时导通,将会烧毁mos管。

根据半桥控制电路原理,将上面的表格进行转换,可以得到6步状态与mos开关的状态对应表,如下表所示

状态
电流方向
U+
U-
W+
W-
V+
V-
6
VW
OFF
OFF
OFF
ON
ON
OFF
2
UW
ON
OFF
OFF
ON
OFF
OFF
3
UV
ON
OFF
OFF
OFF
OFF
ON
1
WV
OFF
OFF
ON
OFF
OFF
ON
5
WU
OFF
ON
ON
OFF
OFF
OFF
4
VU
OFF
OFF
ON
OFF
ON
OFF

如上表,根据6-2-3-1-5-4等状态进行开关对应的mos即可让电机保持持续转动。如果需要让电机反向转动,则状态切换表如下。

状态
电流方向
U+
U-
W+
W-
V+
V-
6
WV
OFF
OFF
ON
OFF
OFF
ON
2
WU
OFF
ON
ON
OFF
OFF
OFF
4
VU
OFF
OFF
ON
OFF
ON
OFF
1
VW
OFF
OFF
OFF
ON
ON
OFF
5
UW
ON
OFF
OFF
ON
OFF
OFF
3
UV
ON
OFF
OFF
OFF
OFF
ON

通过自习对比两个表可以发现,正转状态6mos管开关对应反转的状态1,正转状态2对应反转状态5,正转状态4,对应反转状态3。可以得出如下规律:

反转状态mos切换 = (7-正转状态)模式切换。也就是说,如果与要反转,当前状态6应用使用状态1的mos控制逻辑。

转速调整,在第一篇中介绍了5中pwm的控制方式,这里选用H_PWM-L_ON的方式,即+半桥始终使用PWM控制,-半桥使用高低电平控制。调整pwm占空比,就可以改变电机转动的快慢。

stm32程序设计

上文讲解了6步状态对应mos管的状态控制,正反转控制,以及如何调整电机的转速。接下来,将讲解具体使用代码如何实现6步法,及正反转调速控制。

采用H_PWM-L_ON方式,需要用到9个单片机IO,其中3个IO采用pwm输出,负责控制三个上半桥,这三个IO需要用到同一个TIM;3个采用通用输出IO控制,负责控制3个下半桥;3个采用io输入外部中断,用来采集霍尔传感器切换状态。

状态切换函数

首先需要定义6个mos管控制函数,对应6步。

//V+ PWM ,W- ON,6
void m1_vhwl(void)
{
    TIM1->CCR1=0;
    TIM1->CCR2 = g_bldc_motor1.pwm_duty;
    TIM1->CCR3=0;
    HAL_GPIO_WritePin(M1_LOW_SIDE_W_PORT,M1_LOW_SIDE_W_PIN,GPIO_PIN_SET);
    HAL_GPIO_WritePin(M1_LOW_SIDE_U_PORT,M1_LOW_SIDE_U_PIN,GPIO_PIN_RESET);
    HAL_GPIO_WritePin(M1_LOW_SIDE_V_PORT,M1_LOW_SIDE_V_PIN,GPIO_PIN_RESET);
}
//U+ PWM ,W- ON,2
void m1_uhwl(void)
{
    TIM1->CCR1 = g_bldc_motor1.pwm_duty;
    TIM1->CCR2 = 0;
    TIM1->CCR3 = 0;
    HAL_GPIO_WritePin(M1_LOW_SIDE_W_PORT,M1_LOW_SIDE_W_PIN,GPIO_PIN_SET);
    HAL_GPIO_WritePin(M1_LOW_SIDE_U_PORT,M1_LOW_SIDE_U_PIN,GPIO_PIN_RESET);
    HAL_GPIO_WritePin(M1_LOW_SIDE_V_PORT,M1_LOW_SIDE_V_PIN,GPIO_PIN_RESET);
}
//U+ PWM ,V- ON,3
void m1_uhvl(void)
{
    TIM1.Instance->CCR1 = g_bldc_motor1.pwm_duty;                 
    TIM1->CCR2 = 0;
    TIM1->CCR3 = 0;
    HAL_GPIO_WritePin(M1_LOW_SIDE_V_PORT,M1_LOW_SIDE_V_PIN,GPIO_PIN_SET);   
    HAL_GPIO_WritePin(M1_LOW_SIDE_U_PORT,M1_LOW_SIDE_U_PIN,GPIO_PIN_RESET); 
    HAL_GPIO_WritePin(M1_LOW_SIDE_W_PORT,M1_LOW_SIDE_W_PIN,GPIO_PIN_RESET); 
}
//W+ PWM ,V- ON,1
void m1_whvl(void)
{
    TIM1->CCR1 = 0;
    TIM1->CCR2 = 0;
    TIM1->CCR3 = g_bldc_motor1.pwm_duty;
    HAL_GPIO_WritePin(M1_LOW_SIDE_V_PORT,M1_LOW_SIDE_V_PIN,GPIO_PIN_SET);
    HAL_GPIO_WritePin(M1_LOW_SIDE_U_PORT,M1_LOW_SIDE_U_PIN,GPIO_PIN_RESET);
    HAL_GPIO_WritePin(M1_LOW_SIDE_W_PORT,M1_LOW_SIDE_W_PIN,GPIO_PIN_RESET);
}
//W+ PWM ,U- ON,5
void m1_whul(void)
{
    TIM1->CCR1 = 0;
    TIM1->CCR2 = 0;
    TIM1->CCR3 = g_bldc_motor1.pwm_duty;
    HAL_GPIO_WritePin(M1_LOW_SIDE_U_PORT,M1_LOW_SIDE_U_PIN,GPIO_PIN_SET);
    HAL_GPIO_WritePin(M1_LOW_SIDE_V_PORT,M1_LOW_SIDE_V_PIN,GPIO_PIN_RESET);
    HAL_GPIO_WritePin(M1_LOW_SIDE_W_PORT,M1_LOW_SIDE_W_PIN,GPIO_PIN_RESET);
}
//V+ PWM ,U- ON,4
void m1_vhul(void)
{
    TIM1->CCR1 = 0;
    TIM1->CCR2 = g_bldc_motor1.pwm_duty;
    TIM1->CCR3 = 0;
    HAL_GPIO_WritePin(M1_LOW_SIDE_U_PORT,M1_LOW_SIDE_U_PIN,GPIO_PIN_SET);
    HAL_GPIO_WritePin(M1_LOW_SIDE_V_PORT,M1_LOW_SIDE_V_PIN,GPIO_PIN_RESET);
    HAL_GPIO_WritePin(M1_LOW_SIDE_W_PORT,M1_LOW_SIDE_W_PIN,GPIO_PIN_RESET);
}

状态获取函数

根据霍尔状态,获取到当前状态。

uint32_t hallsensor_get_state(void)
{
    __IO static uint32_t state ;
    state  = 0;
    if(HAL_GPIO_ReadPin(HALL1_TIM_CH1_GPIO,HALL1_TIM_CH1_PIN) != GPIO_PIN_RESET) 
    {
        state |= 0x01U;
    }
    if(HAL_GPIO_ReadPin(HALL1_TIM_CH2_GPIO,HALL1_TIM_CH2_PIN) != GPIO_PIN_RESET)  
    {
        state |= 0x02U;
    }
    if(HAL_GPIO_ReadPin(HALL1_TIM_CH3_GPIO,HALL1_TIM_CH3_PIN) != GPIO_PIN_RESET)  
    {
        state |= 0x04U;
    }
    return state;
}

上面的函数可以使用位域来实现会更简洁。上面函数将霍尔状态按照每个bit放入state变量中。

状态控制函数

void motor_control(void)
{
    uint32_t state = 0;
    if(dir=CW)//正转
    {
        state  =hallsensor_get_state();		
    }
    else
    {
        state  =7-hallsensor_get_state();		
    }
    switch (state)
    {
    case 6:
        m1_vhwl();
        break;
    case 2:
        m1_uhwl();
        break;
    case 3:
        m1_uhvl();
        break;
    case 1:
        m1_whvl();
        break;
    case 5:
        m1_whul();
        break;
    case 4:
        m1_vhul();
        break;
    
    default:
        break;
    }
}

motor_control函数放入,霍尔外部中断函数运行。先获取6步状态,再根据6步状态切换对应的控制函数。

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号