BLDC无刷电机六步换向驱动

发布时间 2023-11-01 21:18:06作者: Yannnnnnn

1.霍尔传感器读数

三路霍尔传感器表示旋转位置,根据霍尔传感器控制电机UVW相;

使用通用定时器TIM5的霍尔传感器模式读取三路霍尔信号跳变:TIM配置为HallSensor模式

TIM_HandleTypeDef h_HALL_TIM = {0};
void HALL_Init(void)
{
    h_HALL_TIM.Instance = TIM5;//APB1,90Mhz 90 000 000
    h_HALL_TIM.Init.Prescaler = 90;
    h_HALL_TIM.Init.CounterMode = TIM_COUNTERMODE_UP;
    h_HALL_TIM.Init.Period = 0xFFFF;
    h_HALL_TIM.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
    h_HALL_TIM.Init.RepetitionCounter = 0;
    h_HALL_TIM.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
    TIM_HallSensor_InitTypeDef HALL_sConfig = {0};
    HALL_sConfig.IC1Polarity = TIM_ICPOLARITY_BOTHEDGE;
    HALL_sConfig.IC1Prescaler = TIM_ICPSC_DIV1;
    HALL_sConfig.IC1Filter = 0x1;
    HALL_sConfig.Commutation_Delay = 0x0000;//霍尔传感器变化后,隔一段时间触发COM事件给TIM8
    HAL_TIMEx_HallSensor_Init(&h_HALL_TIM,&HALL_sConfig);
    HAL_TIMEx_HallSensor_Start_IT(&h_HALL_TIM);//捕获中断
    __HAL_TIM_ENABLE_IT(&h_HALL_TIM,TIM_IT_UPDATE);//使能更新中断
    __HAL_TIM_ENABLE_IT(&h_HALL_TIM,TIM_IT_TRIGGER);//触发中断
}

void HAL_TIMEx_HallSensor_MspInit(TIM_HandleTypeDef *htim)
{
    if(htim->Instance == TIM5)
    {
        __HAL_RCC_TIM5_CLK_ENABLE();
        __HAL_RCC_GPIOH_CLK_ENABLE();
        
        GPIO_InitTypeDef HALL_GPIO_Init = {0};
        HALL_GPIO_Init.Pin = GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12;
        HALL_GPIO_Init.Mode = GPIO_MODE_AF_PP;
        HALL_GPIO_Init.Pull = GPIO_NOPULL;
        HALL_GPIO_Init.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
        HALL_GPIO_Init.Alternate = GPIO_AF2_TIM5;
        HAL_GPIO_Init(GPIOH,&HALL_GPIO_Init);
        
        HAL_NVIC_SetPriority(TIM5_IRQn,0,0);
        HAL_NVIC_EnableIRQ(TIM5_IRQn);
    }
}
/*霍尔值读取函数*/
uint8_t HALL_Read(void)
{
    uint8_t Hall_Num = 0;
    Hall_Num |= (HAL_GPIO_ReadPin(GPIOH,GPIO_PIN_10)<<2);
    Hall_Num |= (HAL_GPIO_ReadPin(GPIOH,GPIO_PIN_11)<<1);
    Hall_Num |= (HAL_GPIO_ReadPin(GPIOH,GPIO_PIN_12)<<0);
    return Hall_Num;
}

2.高级定时器生成PWM波控制电机转速

高级定时器初始化PWM模式:

TIM_HandleTypeDef h_BLDC_PWM_Tim = {0};

void BLDC_TIM_Init(void)
{
    h_BLDC_PWM_Tim.Instance = TIM8;
    h_BLDC_PWM_Tim.Init.Prescaler = 2-1;
    h_BLDC_PWM_Tim.Init.CounterMode = TIM_COUNTERMODE_UP;
    h_BLDC_PWM_Tim.Init.Period = 6000-1;
    h_BLDC_PWM_Tim.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
    h_BLDC_PWM_Tim.Init.RepetitionCounter = 0;
    h_BLDC_PWM_Tim.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
    HAL_TIM_PWM_Init(&h_BLDC_PWM_Tim);
    
    TIM_OC_InitTypeDef BLDC_sConfig = {0};
    BLDC_sConfig.OCMode = TIM_OCMODE_PWM1;
    BLDC_sConfig.Pulse = 0;
    BLDC_sConfig.OCPolarity = TIM_OCPOLARITY_HIGH;
    BLDC_sConfig.OCNPolarity = TIM_OCNPOLARITY_HIGH;
    BLDC_sConfig.OCFastMode = TIM_OCFAST_DISABLE;
    BLDC_sConfig.OCIdleState = TIM_OCIDLESTATE_RESET;
    BLDC_sConfig.OCNIdleState = TIM_OCIDLESTATE_RESET;
    HAL_TIM_OC_ConfigChannel(&h_BLDC_PWM_Tim,&BLDC_sConfig,TIM_CHANNEL_1);
    HAL_TIM_OC_ConfigChannel(&h_BLDC_PWM_Tim,&BLDC_sConfig,TIM_CHANNEL_2);
    HAL_TIM_OC_ConfigChannel(&h_BLDC_PWM_Tim,&BLDC_sConfig,TIM_CHANNEL_3);

    //HAL_TIM_PWM_Start_IT(&h_BLDC_PWM_Tim, uint32_t Channel);
    /*统一控制三个通道输出,TIM5TRGO触发COM*/
    //HAL_TIMEx_ConfigCommutEvent(&h_BLDC_PWM_Tim,TIM_TS_ITR3,TIM_COMMUTATION_TRGI);
}

void HAL_TIM_PWM_MspInit(TIM_HandleTypeDef *htim)
{
    __HAL_RCC_TIM8_CLK_ENABLE();
    __HAL_RCC_GPIOI_CLK_ENABLE();
    __HAL_RCC_GPIOH_CLK_ENABLE();
    GPIO_InitTypeDef PWM_GPIO_Init;
    PWM_GPIO_Init = (GPIO_InitTypeDef){0};
    PWM_GPIO_Init.Pin = GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7;
    PWM_GPIO_Init.Mode = GPIO_MODE_AF_PP;
    PWM_GPIO_Init.Pull = GPIO_NOPULL;
    PWM_GPIO_Init.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    PWM_GPIO_Init.Alternate = GPIO_AF3_TIM8;
    HAL_GPIO_Init(GPIOI,&PWM_GPIO_Init);

    PWM_GPIO_Init = (GPIO_InitTypeDef){0};
    PWM_GPIO_Init.Pin = GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15;
    PWM_GPIO_Init.Mode = GPIO_MODE_OUTPUT_PP;
    PWM_GPIO_Init.Pull = GPIO_NOPULL;
    PWM_GPIO_Init.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    HAL_GPIO_Init(GPIOH,&PWM_GPIO_Init);
}

电机驱动板使能信号:

void BLDC_SHDN(void)
{
    __HAL_RCC_GPIOE_CLK_ENABLE();
    GPIO_InitTypeDef SHDN_GPIO_Init;
    SHDN_GPIO_Init = (GPIO_InitTypeDef){0};
    SHDN_GPIO_Init.Pin = GPIO_PIN_6;
    SHDN_GPIO_Init.Mode = GPIO_MODE_OUTPUT_PP;
    SHDN_GPIO_Init.Pull = GPIO_NOPULL;
    SHDN_GPIO_Init.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    HAL_GPIO_Init(GPIOE,&SHDN_GPIO_Init);
    HAL_GPIO_WritePin(GPIOE,GPIO_PIN_6,GPIO_PIN_SET);//电机驱动板使能信号
}

六步换向函数:

void BLDC_Turn(uint8_t Hall_Num)
{
        if(BLDC_NO1.Turn_Dir)
        {
            /*顺时针*/
            if(Hall_Num == 5){BLDC_UV();}
            if(Hall_Num == 1){BLDC_WV();}
            if(Hall_Num == 3){BLDC_WU();}
            if(Hall_Num == 2){BLDC_VU();}
            if(Hall_Num == 6){BLDC_VW();}
            if(Hall_Num == 4){BLDC_UW();}
        }
        else
        {
            /*逆时针*/
            if(Hall_Num == 5){BLDC_VU();}
            if(Hall_Num == 1){BLDC_VW();}
            if(Hall_Num == 3){BLDC_UW();}
            if(Hall_Num == 2){BLDC_UV();}
            if(Hall_Num == 6){BLDC_WV();}
            if(Hall_Num == 4){BLDC_WU();}
        }
}
void BLDC_UV(void)
{
    __HAL_TIM_SET_COMPARE(&h_BLDC_PWM_Tim, TIM_CHANNEL_1, BLDC_NO1.PWM_Compare);
    __HAL_TIM_SET_COMPARE(&h_BLDC_PWM_Tim, TIM_CHANNEL_2, 0);
    __HAL_TIM_SET_COMPARE(&h_BLDC_PWM_Tim, TIM_CHANNEL_3, 0);
//    HAL_TIM_PWM_Start(&h_BLDC_PWM_Tim,TIM_CHANNEL_1);
//    HAL_TIM_PWM_Stop(&h_BLDC_PWM_Tim,TIM_CHANNEL_2);
//    HAL_TIM_PWM_Stop(&h_BLDC_PWM_Tim,TIM_CHANNEL_3);
    HAL_GPIO_WritePin(GPIOH,GPIO_PIN_13,GPIO_PIN_RESET);
    HAL_GPIO_WritePin(GPIOH,GPIO_PIN_14,GPIO_PIN_SET);
    HAL_GPIO_WritePin(GPIOH,GPIO_PIN_15,GPIO_PIN_RESET);
}
void BLDC_UW(void)
{
    __HAL_TIM_SET_COMPARE(&h_BLDC_PWM_Tim, TIM_CHANNEL_1, BLDC_NO1.PWM_Compare);
    __HAL_TIM_SET_COMPARE(&h_BLDC_PWM_Tim, TIM_CHANNEL_2, 0);
    __HAL_TIM_SET_COMPARE(&h_BLDC_PWM_Tim, TIM_CHANNEL_3, 0);
//    HAL_TIM_PWM_Start(&h_BLDC_PWM_Tim,TIM_CHANNEL_1);
//    HAL_TIM_PWM_Stop(&h_BLDC_PWM_Tim,TIM_CHANNEL_2);
//    HAL_TIM_PWM_Stop(&h_BLDC_PWM_Tim,TIM_CHANNEL_3);
    HAL_GPIO_WritePin(GPIOH,GPIO_PIN_13,GPIO_PIN_RESET);
    HAL_GPIO_WritePin(GPIOH,GPIO_PIN_14,GPIO_PIN_RESET);
    HAL_GPIO_WritePin(GPIOH,GPIO_PIN_15,GPIO_PIN_SET);
}
void BLDC_VW(void)
{
    __HAL_TIM_SET_COMPARE(&h_BLDC_PWM_Tim, TIM_CHANNEL_2, BLDC_NO1.PWM_Compare);
    __HAL_TIM_SET_COMPARE(&h_BLDC_PWM_Tim, TIM_CHANNEL_1, 0);
    __HAL_TIM_SET_COMPARE(&h_BLDC_PWM_Tim, TIM_CHANNEL_3, 0);
//    HAL_TIM_PWM_Stop(&h_BLDC_PWM_Tim,TIM_CHANNEL_1);
//    HAL_TIM_PWM_Start(&h_BLDC_PWM_Tim,TIM_CHANNEL_2);
//    HAL_TIM_PWM_Stop(&h_BLDC_PWM_Tim,TIM_CHANNEL_3);
    HAL_GPIO_WritePin(GPIOH,GPIO_PIN_13,GPIO_PIN_RESET);
    HAL_GPIO_WritePin(GPIOH,GPIO_PIN_14,GPIO_PIN_RESET);
    HAL_GPIO_WritePin(GPIOH,GPIO_PIN_15,GPIO_PIN_SET);
}
void BLDC_VU(void)
{
    __HAL_TIM_SET_COMPARE(&h_BLDC_PWM_Tim, TIM_CHANNEL_2, BLDC_NO1.PWM_Compare);
    __HAL_TIM_SET_COMPARE(&h_BLDC_PWM_Tim, TIM_CHANNEL_1, 0);
    __HAL_TIM_SET_COMPARE(&h_BLDC_PWM_Tim, TIM_CHANNEL_3, 0);
//    HAL_TIM_PWM_Stop(&h_BLDC_PWM_Tim,TIM_CHANNEL_1);
//    HAL_TIM_PWM_Start(&h_BLDC_PWM_Tim,TIM_CHANNEL_2);
//    HAL_TIM_PWM_Stop(&h_BLDC_PWM_Tim,TIM_CHANNEL_3);
    HAL_GPIO_WritePin(GPIOH,GPIO_PIN_13,GPIO_PIN_SET);
    HAL_GPIO_WritePin(GPIOH,GPIO_PIN_14,GPIO_PIN_RESET);
    HAL_GPIO_WritePin(GPIOH,GPIO_PIN_15,GPIO_PIN_RESET);
}
void BLDC_WU(void)
{
    __HAL_TIM_SET_COMPARE(&h_BLDC_PWM_Tim, TIM_CHANNEL_3, BLDC_NO1.PWM_Compare);
    __HAL_TIM_SET_COMPARE(&h_BLDC_PWM_Tim, TIM_CHANNEL_1, 0);
    __HAL_TIM_SET_COMPARE(&h_BLDC_PWM_Tim, TIM_CHANNEL_2, 0);
//    HAL_TIM_PWM_Stop(&h_BLDC_PWM_Tim,TIM_CHANNEL_1);
//    HAL_TIM_PWM_Stop(&h_BLDC_PWM_Tim,TIM_CHANNEL_2);
//    HAL_TIM_PWM_Start(&h_BLDC_PWM_Tim,TIM_CHANNEL_3);
    HAL_GPIO_WritePin(GPIOH,GPIO_PIN_13,GPIO_PIN_SET);
    HAL_GPIO_WritePin(GPIOH,GPIO_PIN_14,GPIO_PIN_RESET);
    HAL_GPIO_WritePin(GPIOH,GPIO_PIN_15,GPIO_PIN_RESET);
}
void BLDC_WV(void)
{
    __HAL_TIM_SET_COMPARE(&h_BLDC_PWM_Tim, TIM_CHANNEL_3, BLDC_NO1.PWM_Compare);
    __HAL_TIM_SET_COMPARE(&h_BLDC_PWM_Tim, TIM_CHANNEL_1, 0);
    __HAL_TIM_SET_COMPARE(&h_BLDC_PWM_Tim, TIM_CHANNEL_2, 0);
//    HAL_TIM_PWM_Stop(&h_BLDC_PWM_Tim,TIM_CHANNEL_1);
//    HAL_TIM_PWM_Stop(&h_BLDC_PWM_Tim,TIM_CHANNEL_2);
//    HAL_TIM_PWM_Start(&h_BLDC_PWM_Tim,TIM_CHANNEL_3);
    HAL_GPIO_WritePin(GPIOH,GPIO_PIN_13,GPIO_PIN_RESET);
    HAL_GPIO_WritePin(GPIOH,GPIO_PIN_14,GPIO_PIN_SET);
    HAL_GPIO_WritePin(GPIOH,GPIO_PIN_15,GPIO_PIN_RESET);
}

电机启动函数:

void BLDC_Start(void)
{
    
    __HAL_TIM_SET_COMPARE(&h_BLDC_PWM_Tim, TIM_CHANNEL_1, 0);
    __HAL_TIM_SET_COMPARE(&h_BLDC_PWM_Tim, TIM_CHANNEL_2, 0);
    __HAL_TIM_SET_COMPARE(&h_BLDC_PWM_Tim, TIM_CHANNEL_3, 0);
    HAL_TIM_PWM_Start(&h_BLDC_PWM_Tim,TIM_CHANNEL_1);
    HAL_TIM_PWM_Start(&h_BLDC_PWM_Tim,TIM_CHANNEL_2);
    HAL_TIM_PWM_Start(&h_BLDC_PWM_Tim,TIM_CHANNEL_3);
    HAL_GPIO_WritePin(GPIOH,GPIO_PIN_13,GPIO_PIN_RESET);
    HAL_GPIO_WritePin(GPIOH,GPIO_PIN_14,GPIO_PIN_RESET);
    HAL_GPIO_WritePin(GPIOH,GPIO_PIN_15,GPIO_PIN_RESET);
    HAL_TIM_GenerateEvent(&h_BLDC_PWM_Tim, TIM_EVENTSOURCE_COM);//软件生成COM事件
    __HAL_TIM_CLEAR_FLAG(&h_BLDC_PWM_Tim,TIM_FLAG_COM);
    HAL_Delay(10);//自举电容充电
    BLDC_Turn(HALL_Read());
    HAL_TIM_GenerateEvent(&h_BLDC_PWM_Tim, TIM_EVENTSOURCE_COM);//软件生成COM事件
    __HAL_TIM_CLEAR_FLAG(&h_BLDC_PWM_Tim,TIM_FLAG_COM);
}

3.通用定时器输入捕获函数中调用六步换向函数:

void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)//输入捕获函数
{
    if(htim->Instance == h_HALL_TIM.Instance)
    {
        //printf("\n Hall_Num=%d,",HALL_Read());
        
        BLDC_Turn(HALL_Read());
    }
}

4.主函数中检测案件控制电机加减速

  while (1)
  {
      
      if(Key_Scan(GPIOA,GPIO_PIN_0)==1)
      {
          BLDC_NO1.Turn_Dir_PWM += 100;
          if(BLDC_NO1.Turn_Dir_PWM>=6000){BLDC_NO1.Turn_Dir_PWM = 6000;}
          if(BLDC_NO1.Turn_Dir_PWM<=-6000){BLDC_NO1.Turn_Dir_PWM = -6000;}
          if(BLDC_NO1.Turn_Dir_PWM >= 0)
          {
              BLDC_NO1.Turn_Dir = 1;
              BLDC_NO1.PWM_Compare = BLDC_NO1.Turn_Dir_PWM;
          }
          else
          {
              BLDC_NO1.Turn_Dir = 0;
              BLDC_NO1.PWM_Compare = -BLDC_NO1.Turn_Dir_PWM;
          }
          BLDC_Start();
          printf("\n PWM=%d,",BLDC_NO1.PWM_Compare);
      }
      if(Key_Scan(GPIOC,GPIO_PIN_13)==1)
      {
          BLDC_NO1.Turn_Dir_PWM -= 100;
          if(BLDC_NO1.Turn_Dir_PWM>=6000){BLDC_NO1.Turn_Dir_PWM = 6000;}
          if(BLDC_NO1.Turn_Dir_PWM<=-6000){BLDC_NO1.Turn_Dir_PWM = -6000;}
          if(BLDC_NO1.Turn_Dir_PWM >= 0)
          {
              BLDC_NO1.Turn_Dir = 1;
              BLDC_NO1.PWM_Compare = BLDC_NO1.Turn_Dir_PWM;
          }
          else
          {
              BLDC_NO1.Turn_Dir = 0;
              BLDC_NO1.PWM_Compare = -BLDC_NO1.Turn_Dir_PWM;
          }
          BLDC_Start();
          printf("\n PWM=%d,",BLDC_NO1.PWM_Compare);
      }
      
  }