【零基础玩转BLDC系列】无刷直流电机无位置传感器三段式启动法详细介绍及代码分享

您所在的位置:网站首页 求助位置传感器 【零基础玩转BLDC系列】无刷直流电机无位置传感器三段式启动法详细介绍及代码分享

【零基础玩转BLDC系列】无刷直流电机无位置传感器三段式启动法详细介绍及代码分享

2023-11-13 00:23| 来源: 网络整理| 查看: 265

无刷直流电动机基本转动原理等内容请参考《基于霍尔传感器的无刷直流电机控制原理》、《基于反电动势过零检测法的无刷直流电机控制原理》与《以GD32F30x为例定时器相关功能详解》,BLDC基本原理及基础知识本篇不再赘述。

直流无刷电机由于定子绕组的反电动势与电机的转速成正比,所以电机在静止时反电动势为零或低速时反电动势很小,此时无法根据反电动势信号确定转子磁极的位置。因此,反电动势法需要采用特殊启动技术,从静止开始加速,直至转速足够大。通过反电势能检测到过零时,再切换至直流无刷电机运行状态。这个过程称为“三段式”启动,主要包括转子预定位、加速和运行状态切换三个阶段。这样既可以使电机转向可控,又可以保证电机达到一定转速后再进行切换,保证了启动的可靠性。

下面对“三段式”启动技术进行详细的分析。

1、电机转子预定位

若要保证直流无刷电机能够正常启动,首先要确定转子在静止时的位置。

在小型轻载条件下,对于具有梯形反电势波形的直流无刷电机来说,一般采用磁制动转子定位方式。系统启动时,任意给定一组触发脉冲,在气隙中形成一个幅值恒定、方向不变的磁通。只要保证其幅值足够大,那么这一磁通就能在一定时间内将电机转子强行定位在这个方向上。

在应用中,可以在任意一组绕组上通电一定时间,其中预定位的PWM占空比和预定位时间的长短设定值可由具体电机特性和负载决定,在实际应用中调试而得。通常为了保险起见,会定位两次相邻的位置,防止转子刚好处于临界位置。

在预定位成功后,转子在启动前可达到预定的位置,为电机启动做好准备。

void motor_lacation_cfg_1() { //W+ U- /* channel0 configuration */ timer_channel_output_mode_config(TIMER0, TIMER_CH_0, TIMER_OC_MODE_PWM0); timer_channel_output_state_config(TIMER0, TIMER_CH_0, TIMER_CCX_DISABLE); timer_channel_complementary_output_state_config(TIMER0, TIMER_CH_0, TIMER_CCXN_ENABLE); /* channel1 configuration */ timer_channel_output_mode_config(TIMER0, TIMER_CH_1, TIMER_OC_MODE_PWM0); timer_channel_output_state_config(TIMER0, TIMER_CH_1, TIMER_CCX_DISABLE); timer_channel_complementary_output_state_config(TIMER0, TIMER_CH_1, TIMER_CCXN_DISABLE); /* channel2 configuration */ timer_channel_output_mode_config(TIMER0, TIMER_CH_2, TIMER_OC_MODE_PWM0); timer_channel_output_state_config(TIMER0, TIMER_CH_2, TIMER_CCX_ENABLE); timer_channel_complementary_output_state_config(TIMER0, TIMER_CH_2, TIMER_CCXN_DISABLE); } void motor_lacation_cfg_2() { //U+ V- /* channel0 configuration */ timer_channel_output_mode_config(TIMER0, TIMER_CH_0, TIMER_OC_MODE_PWM0); timer_channel_output_state_config(TIMER0, TIMER_CH_0, TIMER_CCX_ENABLE); timer_channel_complementary_output_state_config(TIMER0, TIMER_CH_0, TIMER_CCXN_DISABLE); // /* channel1 configuration */ timer_channel_output_mode_config(TIMER0, TIMER_CH_1, TIMER_OC_MODE_PWM0); timer_channel_output_state_config(TIMER0, TIMER_CH_1, TIMER_CCX_DISABLE); timer_channel_complementary_output_state_config(TIMER0, TIMER_CH_1, TIMER_CCXN_ENABLE); /* channel2 configuration */ timer_channel_output_mode_config(TIMER0, TIMER_CH_2, TIMER_OC_MODE_PWM0); timer_channel_output_state_config(TIMER0, TIMER_CH_2, TIMER_CCX_DISABLE); timer_channel_complementary_output_state_config(TIMER0, TIMER_CH_2, TIMER_CCXN_DISABLE); } void motor_lacation_cfg_3() { //W+ V- /* channel0 configuration */ timer_channel_output_mode_config(TIMER0, TIMER_CH_0, TIMER_OC_MODE_PWM0); timer_channel_output_state_config(TIMER0, TIMER_CH_0, TIMER_CCX_DISABLE); timer_channel_complementary_output_state_config(TIMER0, TIMER_CH_0, TIMER_CCXN_DISABLE); /* channel1 configuration */ timer_channel_output_mode_config(TIMER0, TIMER_CH_1, TIMER_OC_MODE_PWM0); timer_channel_output_state_config(TIMER0, TIMER_CH_1, TIMER_CCX_DISABLE); timer_channel_complementary_output_state_config(TIMER0, TIMER_CH_1, TIMER_CCXN_ENABLE); /* channel2 configuration */ timer_channel_output_mode_config(TIMER0, TIMER_CH_2, TIMER_OC_MODE_PWM0); timer_channel_output_state_config(TIMER0, TIMER_CH_2, TIMER_CCX_ENABLE); timer_channel_complementary_output_state_config(TIMER0, TIMER_CH_2, TIMER_CCXN_DISABLE); } void motor_lacation_cfg_4() { //V+ W- /* channel0 configuration */ timer_channel_output_mode_config(TIMER0, TIMER_CH_0, TIMER_OC_MODE_PWM0); timer_channel_output_state_config(TIMER0, TIMER_CH_0, TIMER_CCX_DISABLE); timer_channel_complementary_output_state_config(TIMER0, TIMER_CH_0, TIMER_CCXN_DISABLE); /* channel1 configuration */ timer_channel_output_mode_config(TIMER0, TIMER_CH_1, TIMER_OC_MODE_PWM0); timer_channel_output_state_config(TIMER0, TIMER_CH_1, TIMER_CCX_ENABLE); timer_channel_complementary_output_state_config(TIMER0, TIMER_CH_1, TIMER_CCXN_DISABLE); /* channel2 configuration */ timer_channel_output_mode_config(TIMER0, TIMER_CH_2, TIMER_OC_MODE_PWM0); timer_channel_output_state_config(TIMER0, TIMER_CH_2, TIMER_CCX_DISABLE); timer_channel_complementary_output_state_config(TIMER0, TIMER_CH_2, TIMER_CCXN_ENABLE); } void motor_lacation_cfg_5() { //V+ U- /* channel0 configuration */ timer_channel_output_mode_config(TIMER0, TIMER_CH_0, TIMER_OC_MODE_PWM0); timer_channel_output_state_config(TIMER0, TIMER_CH_0, TIMER_CCX_DISABLE); timer_channel_complementary_output_state_config(TIMER0, TIMER_CH_0, TIMER_CCXN_ENABLE); /* channel1 configuration */ timer_channel_output_mode_config(TIMER0, TIMER_CH_1, TIMER_OC_MODE_PWM0); timer_channel_output_state_config(TIMER0, TIMER_CH_1, TIMER_CCX_ENABLE); timer_channel_complementary_output_state_config(TIMER0, TIMER_CH_1, TIMER_CCXN_DISABLE); /* channel2 configuration */ timer_channel_output_mode_config(TIMER0, TIMER_CH_2, TIMER_OC_MODE_PWM0); timer_channel_output_state_config(TIMER0, TIMER_CH_2, TIMER_CCX_DISABLE); timer_channel_complementary_output_state_config(TIMER0, TIMER_CH_2, TIMER_CCXN_DISABLE); } void motor_lacation_cfg_6() { // U+ W- /* channel0 configuration */ timer_channel_output_mode_config(TIMER0, TIMER_CH_0, TIMER_OC_MODE_PWM0); timer_channel_output_state_config(TIMER0, TIMER_CH_0, TIMER_CCX_ENABLE); timer_channel_complementary_output_state_config(TIMER0, TIMER_CH_0, TIMER_CCXN_DISABLE); /* channel1 configuration */ timer_channel_output_mode_config(TIMER0, TIMER_CH_1, TIMER_OC_MODE_PWM0); timer_channel_output_state_config(TIMER0, TIMER_CH_1, TIMER_CCX_DISABLE); timer_channel_complementary_output_state_config(TIMER0, TIMER_CH_1, TIMER_CCXN_DISABLE); /* channel2 configuration */ timer_channel_output_mode_config(TIMER0, TIMER_CH_2, TIMER_OC_MODE_PWM0); timer_channel_output_state_config(TIMER0, TIMER_CH_2, TIMER_CCX_DISABLE); timer_channel_complementary_output_state_config(TIMER0, TIMER_CH_2, TIMER_CCXN_ENABLE); } void motor_step_stop() { timer_channel_output_pulse_value_config(TIMER0,TIMER_CH_0, 0); timer_channel_output_pulse_value_config(TIMER0,TIMER_CH_1, 0); timer_channel_output_pulse_value_config(TIMER0,TIMER_CH_2, 0); } void motor_locate() { timer_channel_output_pulse_value_config(TIMER0,TIMER_CH_0, 1500); timer_channel_output_pulse_value_config(TIMER0,TIMER_CH_1, 1500); timer_channel_output_pulse_value_config(TIMER0,TIMER_CH_2, 1500); if(CCW==0){ motor_lacation_cfg_4(); timer_enable(TIMER0); delay_1ms(60); motor_lacation_cfg_6(); timer_enable(TIMER0); delay_1ms(60); } else{//逆时针 motor_lacation_cfg_3(); timer_enable(TIMER0); delay_1ms(60); motor_lacation_cfg_2(); timer_enable(TIMER0); delay_1ms(60); } motor_step_stop(); timer_disable(TIMER0); } 2、电机的外同步加速

确定了电机转子的初始位置后,由于此时定子绕组中的反电动势仍为零,所以须人为改变电机的外施电压和换相信号,使电机由静止逐步加速运动。这一过程称为外同步加速。对于不同的外施电压调整方法和换相信号调整方法,外同步加速可划分为三类:

①换相信号频率不变,逐步增大外施电压使电机加速,称为恒频升压法。

②保持外施电压不变,逐渐增高换相信号的频率,使电机逐步加速,称为恒压升频法。

③在逐步增大外施电压的同时,增高换相的频率,称为升频升压法。

各个方法都有其优点和缺点。如升频升压法是人为地给电机施加一个由低频到高频不断加速的他控同步切换信号,而且电压也在不断地增加。通过调整电机换相频率,即可调整电机启动的速度。调整方法比较简单。但是这个过程较难实现。切换信号的频率的选择要根据电机的极对数和其他参数来确定。太低,电机无法加速;太高,电机转速达不到,会有噪声甚至无法启动,算法比较困难。

无论哪种方法,该过程都是在未检测到反电动势信号时进行。因此对于控制系统来说此段电机控制是盲区。参数在调试好的时候,可以快速切换至正常运行状态;而参数不理想时,电流可能不稳甚至电机会抖动。因此,在应用中,应根据电机及负载特性设定合理的升速曲线,并在尽可能短的时间内完成切换。

void openloop_step_change(uint32_t pwm_duty,uint32_t counter) { timer_channel_output_pulse_value_config(TIMER0,TIMER_CH_0, pwm_duty); timer_channel_output_pulse_value_config(TIMER0,TIMER_CH_1, pwm_duty); timer_channel_output_pulse_value_config(TIMER0,TIMER_CH_2, pwm_duty); if(CCW==0){//顺时针 motor_lacation_cfg_2(); delay_1us(counter); motor_lacation_cfg_3(); delay_1us(counter); motor_lacation_cfg_1(); delay_1us(counter); motor_lacation_cfg_5(); delay_1us(counter); motor_lacation_cfg_4(); delay_1us(counter); motor_lacation_cfg_6(); delay_1us(counter);} else{//逆时针 motor_lacation_cfg_6(); delay_1us(counter); motor_lacation_cfg_4(); delay_1us(counter); motor_lacation_cfg_5(); delay_1us(counter); motor_lacation_cfg_1(); delay_1us(counter); motor_lacation_cfg_3(); delay_1us(counter); motor_lacation_cfg_2(); delay_1us(counter);} } void motor_openloop() { int i=0; timer_enable(TIMER0); for(i=0;i


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3