無刷直流電動機基本轉(zhuǎn)動原理等內(nèi)容請參考《基于霍爾傳感器的無刷直流電機控制原理》、《基于反電動勢過零檢測法的無刷直流電機控制原理》與《以GD32F30x為例定時器相關功能詳解》,BLDC基本原理及基礎知識本篇不再贅述。
直流無刷電機由于定子繞組的反電動勢與電機的轉(zhuǎn)速成正比,所以電機在靜止時反電動勢為零或低速時反電動勢很小,此時無法根據(jù)反電動勢信號確定轉(zhuǎn)子磁極的位置。因此,反電動勢法需要采用特殊啟動技術,從靜止開始加速,直至轉(zhuǎn)速足夠大。通過反電勢能檢測到過零時,再切換至直流無刷電機運行狀態(tài)。這個過程稱為“三段式”啟動,主要包括轉(zhuǎn)子預定位、加速和運行狀態(tài)切換三個階段。這樣既可以使電機轉(zhuǎn)向可控,又可以保證電機達到一定轉(zhuǎn)速后再進行切換,保證了啟動的可靠性。
下面對“三段式”啟動技術進行詳細的分析。
1、電機轉(zhuǎn)子預定位
若要保證直流無刷電機能夠正常啟動,首先要確定轉(zhuǎn)子在靜止時的位置。
在小型輕載條件下,對于具有梯形反電勢波形的直流無刷電機來說,一般采用磁制動轉(zhuǎn)子定位方式。系統(tǒng)啟動時,任意給定一組觸發(fā)脈沖,在氣隙中形成一個幅值恒定、方向不變的磁通。只要保證其幅值足夠大,那么這一磁通就能在一定時間內(nèi)將電機轉(zhuǎn)子強行定位在這個方向上。
在應用中,可以在任意一組繞組上通電一定時間,其中預定位的PWM占空比和預定位時間的長短設定值可由具體電機特性和負載決定,在實際應用中調(diào)試而得。通常為了保險起見,會定位兩次相鄰的位置,防止轉(zhuǎn)子剛好處于臨界位置。
在預定位成功后,轉(zhuǎn)子在啟動前可達到預定的位置,為電機啟動做好準備。
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、電機的外同步加速
確定了電機轉(zhuǎn)子的初始位置后,由于此時定子繞組中的反電動勢仍為零,所以須人為改變電機的外施電壓和換相信號,使電機由靜止逐步加速運動。這一過程稱為外同步加速。對于不同的外施電壓調(diào)整方法和換相信號調(diào)整方法,外同步加速可劃分為三類:
①換相信號頻率不變,逐步增大外施電壓使電機加速,稱為恒頻升壓法。
②保持外施電壓不變,逐漸增高換相信號的頻率,使電機逐步加速,稱為恒壓升頻法。
③在逐步增大外施電壓的同時,增高換相的頻率,稱為升頻升壓法。
各個方法都有其優(yōu)點和缺點。如升頻升壓法是人為地給電機施加一個由低頻到高頻不斷加速的他控同步切換信號,而且電壓也在不斷地增加。通過調(diào)整電機換相頻率,即可調(diào)整電機啟動的速度。調(diào)整方法比較簡單。但是這個過程較難實現(xiàn)。切換信號的頻率的選擇要根據(jù)電機的極對數(shù)和其他參數(shù)來確定。太低,電機無法加速;太高,電機轉(zhuǎn)速達不到,會有噪聲甚至無法啟動,算法比較困難。
無論哪種方法,該過程都是在未檢測到反電動勢信號時進行。因此對于控制系統(tǒng)來說此段電機控制是盲區(qū)。參數(shù)在調(diào)試好的時候,可以快速切換至正常運行狀態(tài);而參數(shù)不理想時,電流可能不穩(wěn)甚至電機會抖動。因此,在應用中,應根據(jù)電機及負載特性設定合理的升速曲線,并在盡可能短的時間內(nèi)完成切換。
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<192;i++)
{
openloop_step_change(1600,60000-300*i);
}
for(i=0;i<800;i++)
{
openloop_step_change(1600,2700);
}
}
3、電機運行狀態(tài)的轉(zhuǎn)換
當電機通過外同步加速到一定的轉(zhuǎn)速,反電勢信號可以準確檢測時,即可由外同步向自同步切換??梢酝ㄟ^試驗觀察反電勢信號能夠被準確檢測的轉(zhuǎn)速。在進行切換有兩種方法:一種是測速模塊可以測出電機的轉(zhuǎn)速,當達到這一轉(zhuǎn)速時即可進行切換;另一種,通過試驗檢測出達到預定切換轉(zhuǎn)速的時間,通過軟件定時器設置切換時間。
這一步是關鍵也是比較難實現(xiàn)的一步。有時軟件或者硬件設計的不合理都可能導致啟動失敗。通常是采用估算的方式來選擇切換速度。文章來源:http://www.zghlxwxcb.cn/news/detail-403248.html
void motor_sensorless_start()
{
timer_channel_control_shadow_config(TIMER0,ENABLE); //開始從外同步切入自同步模式,即使用過零點檢測法檢測位置
timer_enable(TIMER2);
while(speed_count>1300){} //自同步模式切入后會有短暫的升速階段,通過判斷速度等待并確認自同步成功切入
CloseLoop_Start=1; //閉環(huán)標志位置位,后續(xù)進行閉環(huán)控制
}
int main(void)
{
systick_config();
bldc_gpio_config(); // all gpio
PID_init( &Speed_Ctrl, PID_Speed, I_ref_Max, 0.0f);
PID_init( &I_Ctrl, PID_I, PWM_Duty_Max, 0.0f);
NVIC_CFG();
dma_config();
adc_config();
TimerIn_config();
TimerOut_config();
motor_locate(); //定位
motor_openloop(); //外同步
motor_sensorless_start(); //自同步-閉環(huán)
while (1){
}
}
通過上面的分析可知,無位置傳感器直流無刷電機控制系統(tǒng)的難點就是加速及切換階段。當電機順利啟動后,就可以對電機進行調(diào)速操作。其中,無位置傳感器直流無刷電機和有位置傳感器直流無刷電機調(diào)速原理一致。但,由于無感三段式啟動過程,轉(zhuǎn)子位置檢測無效。因此,對電機進行的速度PID閉環(huán)控制,須在電機啟動順利完成后進行。文章來源地址http://www.zghlxwxcb.cn/news/detail-403248.html
到了這里,關于【零基礎玩轉(zhuǎn)BLDC系列】無刷直流電機無位置傳感器三段式啟動法詳細介紹及代碼分享的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!