【嵌入式电机控制#23】BLDC:开环运动控制框架
此章对上节内容进行补充,增加了调速、刹车充电一体化等运动控制功能,是后续机器人、飞行器底层驱动编写的基础,此框架务必熟悉。
一、制动+充电融合处理
短路制动属于能耗制动的一种,这种技术广泛运用于汽车电子、机器人领域,本专栏讲解的只是一个基础的例子。
void BLDCMotor_braking_LowerShort()
{/* ÏȽûÖ¹ÖжÏ,·Àֹɲ³µ¹ý³Ì´¥·¢COMʼþÖØÐÂÊä³ö */HAL_TIMEx_HallSensor_Stop_IT(&htimx_hall);//上桥臂全部关断,下桥臂全部导通__HAL_TIM_SET_COMPARE(&htimx_BLDCM, BLDCMOTOR_TIM_CH1, 0);// Èç¹ûÐèÒªµ¼Í¨ÉÏÇűÛ__HAL_TIM_SET_COMPARE(&htimx_BLDCM, BLDCMOTOR_TIM_CH2, 0);// Õ¼¿Õ±ÈÉèÖÃΪ100%__HAL_TIM_SET_COMPARE(&htimx_BLDCM, BLDCMOTOR_TIM_CH3, 0);// ¼´¿ÉHAL_TIM_PWM_Start(&htimx_BLDCM, BLDCMOTOR_TIM_CH1);HAL_TIM_PWM_Start(&htimx_BLDCM, BLDCMOTOR_TIM_CH2);HAL_TIM_PWM_Start(&htimx_BLDCM, BLDCMOTOR_TIM_CH3);HAL_TIMEx_PWMN_Start(&htimx_BLDCM, BLDCMOTOR_TIM_CH1);HAL_TIMEx_PWMN_Start(&htimx_BLDCM, BLDCMOTOR_TIM_CH2);HAL_TIMEx_PWMN_Start(&htimx_BLDCM, BLDCMOTOR_TIM_CH3);//更新COMHAL_TIM_GenerateEvent(&htimx_BLDCM, TIM_EVENTSOURCE_COM); __HAL_TIM_CLEAR_FLAG(&htimx_BLDCM, TIM_FLAG_COM);//电机状态标志位改变Motor_State = MOTOR_DISABLE;
}
if(KEY_StateRead(KEY1_GPIO_Port,KEY1_Pin) == KEY_DOWN){BLDCMotor_Braking_LowerShort();//主函数中调用短路制动HAL_Delay(100);// delay对于某些速度可能不够 需要自己调BLDCMotor_unbraking_LS();BLDCM_Inertia_brake();Speed = 0.0f;}
制动结束后必须关闭PWM
void BLDCMotor_unbraking_LS(void)
{/* ¹Ø±ÕÊä³ö */HAL_TIM_PWM_Stop(&htim1, TIM_CHANNEL_1);HAL_TIM_PWM_Stop(&htim1, TIM_CHANNEL_2);HAL_TIM_PWM_Stop(&htim1, TIM_CHANNEL_3);HAL_TIMEx_PWMN_Stop(&htim1, TIM_CHANNEL_1);HAL_TIMEx_PWMN_Stop(&htim1, TIM_CHANNEL_2);HAL_TIMEx_PWMN_Stop(&htim1, TIM_CHANNEL_3);//记住,每大量操作PWM一次,就要更新COMHAL_TIM_GenerateEvent(&htim1, TIM_EVENTSOURCE_COM);
}
关闭PWM后关闭驱动芯片
void BLDCM_Inertia_brake(void)
{BLDCMOTOR_DISABLE(); Motor_State = MOTOR_DISABLE;
}//当然,这也可以单独当作一种惯性制动方法
二、电机开启
void BLDCMotor_Start(void)
{ uint32_t hallPhase = 0;BLDCMOTOR_ENABLE();// 电机驱动芯片开启BLDCMotor_Braking_LowerShort();HAL_Delay(9); //电容充电,记得根据实际情况调整时间//清空霍尔捕获值再重新打开霍尔中断,防止上次转动的捕获影响本次转动__HAL_TIM_CLEAR_FLAG(&htim5, TIM_FLAG_CC1);HAL_TIMEx_HallSensor_Start_IT(&htim5);hallPhase = HALL_GetPhase(); // 获取相位//换相BLDCMotor_PhaseCtrl(hallPhase); HAL_TIM_GenerateEvent(&htim1, TIM_EVENTSOURCE_COM); //更新COM事件__HAL_TIM_CLEAR_FLAG(&htim1, TIM_FLAG_COM); //清除COM标志位Motor_State = MOTOR_ENABLE;//变更状态为开启printf("BLDC started\r\n");
}
三、实现调速
void BLDCMotor_SetSpeed(float speed)
{if(speed > 1.0f){speed = 1.0f;//这里暂时用占空比替代速度,如果有粗略的开环关系可以套进来}else if(speed < 0.0f){speed = 0.0f;}//二次限幅PWM_set = speed;
}
实现加减速,注意在speed=0且电压较低时的时候不能加0.05,而是加到0.15,否则可能会进入死区
此外,速度如果加的太高,短路制动时间要延长
if(KEY_StateRead(KEY0_GPIO_Port, KEY0_Pin) == KEY_DOWN){if( Speed == 0.0f ){Speed += 0.15f; // 15% Æô¶¯BLDCMotor_SetSpeed( Speed );BLDCMotor_Start();}else{Speed += 0.05f; // ËٶȵÝÔö 5%if( Speed >= 1.0f ){Speed = 1.0f;}BLDCMotor_SetSpeed( Speed );} }if(KEY4_StateRead() == KEY_DOWN){MotorSpeed -= 0.05f; if( MotorSpeed <= 0.0f ){MotorSpeed = 0.0f;}//注意占空比限幅BLDCMotor_SetSpeed( MotorSpeed );}if(KEY_StateRead(KEY1_GPIO_Port,KEY1_Pin) == KEY_DOWN){BLDCMotor_Braking_LowerShort();HAL_Delay(100);// µÈ100ms, µç»úÍ£ÏÂÀ´Ö®ºó²ÅÈ¡Ïûɲ³µ¿ØÖÆBLDCMotor_unbraking_LS();BLDCM_Inertia_brake();Speed = 0.0f;}
四、实现正反向
这里必须注意,无论在机器人还是四轴飞行器开发中,电机必须先停止再转向,否则会对电机内部造成严重损害
if(KEY2_StateRead() == KEY_DOWN){//读取对应按键,我这里按键不够,所以省略IO和引脚BLDCMotor_Braking_LowerShort();HAL_Delay(100); //必须先停止再转向,不然会对电机有严重损害if(Motor_Dir == MOTOR_DIR_CW)//反相操作{ Motor_Dir = MOTOR_DIR_CCW; }else{ Motor_Dir = MOTOR_DIR_CW; }}
此框架用于集中解决工业场合静态无刷电机的问题,为后续面向机器人、飞行器的电控提供基础。