首页 > 其他分享 >BLDC无刷电机六步换向驱动

BLDC无刷电机六步换向驱动

时间:2023-11-01 21:25:24浏览次数:38  
标签:六步 HAL Tim BLDC TIM 换向 GPIO PWM

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);
      }
      
  }

 

标签:六步,HAL,Tim,BLDC,TIM,换向,GPIO,PWM
From: https://www.cnblogs.com/Yannnnnn/p/17804130.html

相关文章

  • 六步教你搭建HTTPS代理服务器
    在当今互联网环境中,保护数据传输安全至关重要。本文将分享一个简单而强大的方法,通过一键搭建HTTPS代理服务器来加密和保护您的网络通信。无论是个人使用还是企业部署,这篇文章都会为您提供详细且易于操作的指南。第一步:选择适合你需求的工具1.Nginx+Let'sEncrypt:......
  • TIM-有感BLDC实现解析-基于CH32V203
    TIM-有感BLDC实现解析-基于CH32V2031、BLDC运行基本原理简要介绍在图1-20(a)中,AB相通电,电流处于转子产生的磁场内,根据左手定则,我们判断线圈AA’中的上半部导线A受到一个顺时针方向的电磁力,而AA’的下半部导线A’也受到一个顺时针方向的电磁力。由于线圈绕组在定子上,定子是固定不......
  • 时间管理-时间的矛盾特征+时间管理的六步法则+时间管理的工具和技巧
    一、时间的矛盾特征时间浪费的角色:二、时间管理的六步法则1.意识认知法提升认知提前规划学会聚焦主动管理2.行为清单法3.整合优化法4.四项类别法判断这些事情与单位的影响程度5.标准执行法6.早思晚省早上:1.六大目标2.快乐、高效完成3.与朋友、......
  • 六步带你体验EDS交换数据全流程
    本期我们将走进XX医疗集团向某慢病院共享数据的场景,如何通过EDS完成数据交换,进而实现医疗数据的安全可控共享。本文分享自华为云社区《【EDS从小白到专家】第1期—六步带你体验EDS交换数据全流程》,作者:开天aPaaS小助手。本期我们将走进XX医疗集团向某慢病院共享数据的场景,如......
  • BLDC无刷直流驱动控制板资料,可驱动300W电机,已量产(STM32 CAN总线)输入电压:15~36V
    BLDC无刷直流驱动控制板资料,可驱动300W电机,已量产(STM32CAN总线)输入电压:15~36V驱动功率:300W~500W,20A电流检测,CAN通信总线功能介绍KEY1:运行KEY2:停止VR1:转速调节带霍尔传感器提供工程原理图和源码,AD9工程内有提供电机型号ID:1759609955138630......
  • 辅导六步法
    1我说你听。2你说我听。3我做你看。4我带你做。5你做我看。6你自己做。 带新人是一件需要耐心和技巧的任务,六部法是一种常用于辅导新人的方法。它是由英国的人力资源专家罗宾·丹尼尔斯(RobinDaniels)提出的,包含以下六个部分:目标设定(GoalSetting):设定明确的工作目标......
  • rt下降40%?程序并行优化六步法
    1背景性能优化是我们日常工作中很重要的一部分,主要有以下原因:降低服务器和带宽等硬件成本:用更少的资源处理更多的请求提高现实世界的运行效率:人机处理效率存在数量级的偏差,同样机器世界的效率提升能带来现实世界效率提升的方法效果提高用户的体验:解决响应缓慢、宕机等问题......
  • STM32F051 MK电调 BLDC 直流无刷电机控制 基于STM32F051 cortex-M0
    STM32F051MK电调BLDC直流无刷电机控制基于STM32F051cortex-M0的电调开发板,包含原理图PCB工程文件,程序源码,BLDC控制入门资料,供初学者入门学习了解。ID:48299619798638569......
  • 电机控制源码 电机控制源码,BLDC无刷直流电机基于stm3 2F1的有传感器和无传感驱动 直流
    电机控制源码电机控制源码,BLDC无刷直流电机基于stm32F1的有传感器和无传感驱动直流无刷电机有传感器和无传感驱动程序识货的赶紧上车。无传感的的实现是基于反电动势过零点实现的,无传感是霍尔实现,可供学习参考,程序有详细注释。实验学习内容1)直流无刷霍尔传感方波速度、电流、双......
  • 电机控制器,BLDC无刷直流电机Simulink模型(数学方法搭建) 版本:m
    电机控制器,BLDC无刷直流电机Simulink模型(数学方法搭建)版本:marlab2018a,可生成低版本包括:模型,设计文档,电机参数m文件仿真时在第三秒加入3Nm的负载,图中为模型和仿真结果(输出扭矩,转速,转子位置,机械角度)模型优点:纯数学方法搭建,可生成代码刷进控制器做SIL测试(simscape搭建的模型无法生......