> 文档中心 > 【GD32F427开发板试用】BLDC方波驱动测试

【GD32F427开发板试用】BLDC方波驱动测试


本篇文章来自极术社区与兆易创新组织的GD32F427开发板评测活动,更多开发板试用活动请关注极术社区网站。作者:szit

0 引

GD32F427V-START开发板采用主控芯片GD32F427VKT6,MCU基于 Arm® Cortex®-M4内核,系统时钟的最大运行时钟频率可以达到240MHz。本次测试利用STM32CubeMX(STM32F427VITx)生成工程代码,完成无刷电机驱动程序输出。GD外设编号从0开始,如TIM0等效STM32的TIM1。本测试目前没有用实际电机测试,用模拟hall时序输出到hall输入引脚的办法,触发换相。外设使用情况如下:

  1. TIM1-CH1/CH1N/CH2/CH2N/CH3/CH3N,三相互补PWM输出;
  2. TIM1-BKN PA6 刹车输入;
  3. TIM3-HALL CH1/CH2/CH3–PB4/PC7/PC8,三相霍尔捕获;
  4. GPIO输出模拟霍尔数字信号输出到TIM3-HALL PC0 /PC1 /PC2
  5. LED-PC6
  6. KEY-PA0

注:本实例需要对有感BLDC驱动硬件与驱动方法有一定理解,比如三相H桥、3相霍尔(120°)、正反转时序等。

1 STM32CubeMX配置

  1. 芯片选择STM32F427VITx(其他未测)
  2. SWD配置
  3. RCC时钟:外置HSE- 25MHZ 外置RTC- 32.768KHz
  4. 时钟配置为180MHz
  5. PC0、PC1、PC2、PC6配置为GPIO_Output,高速
  6. PA0配置为GPIO_Input,上拉
  7. TIM1配置前3个通道三路互补20kHz PWM输出,Prescaler=0,Counter Period = 8899;Activate-Break-Input刹车,BRK State使能 极性为low;PWM模式默认mode1,极性均为High,Idle State为Reset,PA6配置为上拉(低电平刹车,高电平工作);
  8. TIM3配置为XOR ON/Hall Sensor Mode,Prescaler=89,Counter Period = 65535;计数脉冲周期为1us,当产生霍尔捕获中断时获取当前时间即可,一次时间不要超过65535*1us即可,否则会溢出后再计数。

2 程序设计

1.启动Keil,芯片选择GD32F427VK,Debug选择CMSIS-DAP Debugger。
2.启动SYSTICK时钟
配置1ms中断SYSTICK时钟。
`void SysTick_Handler(void)
{
/USER CODE BEGIN SysTick_IRQn 0/

HAL_SYSTICK_IRQHandler();

/USER CODE END SysTick_IRQn 0/
HAL_IncTick();
/USER CODE BEGIN SysTick_IRQn 1/

/USER CODE END SysTick_IRQn 1/
}`
3.在SYSTICK回调函数中输出HALL模拟时序
电机正传与反转时,霍尔都有相应的时序被检测到,这里用模拟的方法输出三相霍尔信号PC0/PC1/PC2到霍尔传感器输入引脚(杜邦线)PB4/PC7/PC8.

#define CNT_PSC   100  uint32_t CounterPSC = CNT_PSC;   int8_t hal_step_simulate=-1;uint8_t array_cw[6] = {2,3,1,5,4,6};uint8_t array_ccw[6] = {5,1,3,2,6,4};void HAL_SYSTICK_Callback(){  CounterPSC--;  if(!CounterPSC)   {  hal_step_simulate++; if(hal_step_simulate==6)hal_step_simulate=0;     if(Motor_Dir == MOTOR_DIR_CW) {     if((array_cw[hal_step_simulate]&0x01)!=0)  HAL_GPIO_WritePin(GPIOC,GPIO_PIN_0,GPIO_PIN_SET);     else  HAL_GPIO_WritePin(GPIOC,GPIO_PIN_0,GPIO_PIN_RESET);   if((array_cw[hal_step_simulate]&0x02)!=0)  HAL_GPIO_WritePin(GPIOC,GPIO_PIN_1,GPIO_PIN_SET);     else  HAL_GPIO_WritePin(GPIOC,GPIO_PIN_1,GPIO_PIN_RESET);   if((array_cw[hal_step_simulate]&0x04)!=0)  HAL_GPIO_WritePin(GPIOC,GPIO_PIN_2,GPIO_PIN_SET);     else  HAL_GPIO_WritePin(GPIOC,GPIO_PIN_2,GPIO_PIN_RESET); } else if(Motor_Dir == MOTOR_DIR_CCW) {     if((array_ccw[hal_step_simulate]&0x01)!=0)  HAL_GPIO_WritePin(GPIOC,GPIO_PIN_0,GPIO_PIN_SET);     else  HAL_GPIO_WritePin(GPIOC,GPIO_PIN_0,GPIO_PIN_RESET);   if((array_ccw[hal_step_simulate]&0x02)!=0)  HAL_GPIO_WritePin(GPIOC,GPIO_PIN_1,GPIO_PIN_SET);     else  HAL_GPIO_WritePin(GPIOC,GPIO_PIN_1,GPIO_PIN_RESET);   if((array_ccw[hal_step_simulate]&0x04)!=0)  HAL_GPIO_WritePin(GPIOC,GPIO_PIN_2,GPIO_PIN_SET);     else  HAL_GPIO_WritePin(GPIOC,GPIO_PIN_2,GPIO_PIN_RESET);     }    CounterPSC = CNT_PSC;    // BLDCMotor_PhaseCtrl(&uwStep);// ¿ØÖÆ6²½PWM»»Ïà  }}

4.换相
根据三相霍尔状态切换3相6路PWM输出。

#define MOTOR_DIR_CCW 1#define MOTOR_DIR_CW 2uint8_t Motor_Dir = 1;void BLDCMotor_PhaseCtrl(int32_t HALLPhase){  if(MOTOR_DIR_CCW == Motor_Dir)    HALLPhase = 0x07 ^ HALLPhase;// ½«µÍÈýλÒì»ò 111b ^ 010b -> 101b  switch(HALLPhase)  {    case 5: //B+  A-    {      /*  Channe3 configuration */HAL_TIM_PWM_Stop(&htim1, TIM_CHANNEL_3);      HAL_TIMEx_PWMN_Stop(&htim1, TIM_CHANNEL_3);   /*  Channe2 configuration  */      __HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_2,BLDCMOTOR_TIM_PERIOD * PWM_Duty);      HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_2);      HAL_TIMEx_PWMN_Stop(&htim1, TIM_CHANNEL_2);/*  Channe1 configuration */      __HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1,BLDCMOTOR_TIM_PERIOD +1);      HAL_TIM_PWM_Stop(&htim1, TIM_CHANNEL_1);      HAL_TIMEx_PWMN_Start(&htim1, TIM_CHANNEL_1);    }    break; case 4:// C+ A-    {      /*  Channe2 configuration */HAL_TIM_PWM_Stop(&htim1, TIM_CHANNEL_2);      HAL_TIMEx_PWMN_Stop(&htim1, TIM_CHANNEL_2);/*  Channe3 configuration  */      __HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_3,BLDCMOTOR_TIM_PERIOD * PWM_Duty);      HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_3);      HAL_TIMEx_PWMN_Stop(&htim1, TIM_CHANNEL_3);/*  Channe1 configuration  */      __HAL_TIM_SET_COMPARE(&htim1,TIM_CHANNEL_1,BLDCMOTOR_TIM_PERIOD +1);      HAL_TIM_PWM_Stop(&htim1, TIM_CHANNEL_1);      HAL_TIMEx_PWMN_Start(&htim1, TIM_CHANNEL_1);    }      break; case 6://C+ B-    {      /*  Channe1 configuration  */HAL_TIM_PWM_Stop(&htim1, TIM_CHANNEL_1);      HAL_TIMEx_PWMN_Stop(&htim1, TIM_CHANNEL_1);   /*  Channe3 configuration */      __HAL_TIM_SET_COMPARE(&htim1,TIM_CHANNEL_3,BLDCMOTOR_TIM_PERIOD * PWM_Duty);      HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_3);      HAL_TIMEx_PWMN_Stop(&htim1, TIM_CHANNEL_3); /*  Channe2 configuration  */      __HAL_TIM_SET_COMPARE(&htim1,TIM_CHANNEL_2,BLDCMOTOR_TIM_PERIOD +1);      HAL_TIM_PWM_Stop(&htim1, TIM_CHANNEL_2);      HAL_TIMEx_PWMN_Start(&htim1, TIM_CHANNEL_2);    }      break;    case 2: // A+ B-    {      /*  Channe3 configuration */      HAL_TIM_PWM_Stop(&htim1, TIM_CHANNEL_3);      HAL_TIMEx_PWMN_Stop(&htim1, TIM_CHANNEL_3);   /*  Channe1 configuration */      __HAL_TIM_SET_COMPARE(&htim1,TIM_CHANNEL_1,BLDCMOTOR_TIM_PERIOD * PWM_Duty);      HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1);      HAL_TIMEx_PWMN_Stop(&htim1, TIM_CHANNEL_1);/*  Channe2 configuration */      __HAL_TIM_SET_COMPARE(&htim1,TIM_CHANNEL_2,BLDCMOTOR_TIM_PERIOD +1);      HAL_TIM_PWM_Stop(&htim1, TIM_CHANNEL_2);      HAL_TIMEx_PWMN_Start(&htim1, TIM_CHANNEL_2);    }      break;     case 3:// A+ C-    {      /*  Channe2 configuration */HAL_TIM_PWM_Stop(&htim1, TIM_CHANNEL_2);      HAL_TIMEx_PWMN_Stop(&htim1, TIM_CHANNEL_2);      /*  Channe1 configuration */      __HAL_TIM_SET_COMPARE(&htim1,TIM_CHANNEL_1,BLDCMOTOR_TIM_PERIOD * PWM_Duty);      HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1);      HAL_TIMEx_PWMN_Stop(&htim1, TIM_CHANNEL_1);/*  Channe3 configuration */      __HAL_TIM_SET_COMPARE(&htim1,TIM_CHANNEL_3,BLDCMOTOR_TIM_PERIOD +1);   HAL_TIM_PWM_Stop(&htim1, TIM_CHANNEL_3);      HAL_TIMEx_PWMN_Start(&htim1, TIM_CHANNEL_3);    }      break;    case 1: // B+ C-    {      /*  Channe1 configuration */HAL_TIM_PWM_Stop(&htim1, TIM_CHANNEL_1);      HAL_TIMEx_PWMN_Stop(&htim1, TIM_CHANNEL_1);   /*  Channe2 configuration */      __HAL_TIM_SET_COMPARE(&htim1,TIM_CHANNEL_2, BLDCMOTOR_TIM_PERIOD * PWM_Duty);      HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_2);      HAL_TIMEx_PWMN_Stop(&htim1, TIM_CHANNEL_2);/*  Channe3 configuration */      __HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_3, BLDCMOTOR_TIM_PERIOD +1);      HAL_TIM_PWM_Stop(&htim1, TIM_CHANNEL_3);      HAL_TIMEx_PWMN_Start(&htim1, TIM_CHANNEL_3);    }    break;  }}

5.霍尔捕获
霍尔捕获后,获取当前霍尔值,而后根据霍尔值切换H桥PWM输出,每次捕获可以记录2次捕获之间的时间,可以用于计算转速。

uint8_t hal_state = 0;uint16_t hal_counter=0;uint16_t  RT_hallcomp=0;//hall period cntvoid HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim){    //PB4 PC7 PC8 TIM3    if(TIM3== htim->Instance){  hal_counter++;//test  hal_state = 0; hal_state |= HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_4);//U(A) hal_state <<= 1; hal_state |= HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_7);//V(B) hal_state <<= 1; hal_state |= HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_8);//W(C)  RT_hallcomp = __HAL_TIM_GET_COMPARE(htim,TIM_CHANNEL_1); // for speed  BLDCMotor_PhaseCtrl(hal_state);// update phase    }}

6.其他
在main函数中启动hall定时器
HAL_TIMEx_HallSensor_Start_IT(&htim3);

3 波形测试

刹车低电平刹车,高电平可以正常输出,逻辑分析仪测量6路PWM输出,

【GD32F427开发板试用】BLDC方波驱动测试

4 后续

先发布后修改。在使用过程中,好像TIM2的hall有一路不行,一直跳变,后改用TIM3,GPIO输出有一路需要设置为高速,原因未深究,后发现可能硬件冲突,部分使用的口连接到USB了。