理論


為了實現步進電機的平緩啟停以及避免轉高轉速時不失步停轉。在步進電機啟動、停止過程中,需要採用加減速的演算法對啟動過程進行控制。S曲線是加減速控制最理想的方案。但是S曲線的公式以及控制過程都比較複雜。基於單片機實現這一演算法需要有深厚的數學以及單片機軟體設計能力。
本視頻從淺入深介紹S曲線加減數的理論、編程與實踐。
將S曲線離散化,在整個加減速過程中,以一定的時間間隔更新頻率,總的更新次數為2*N,i表示為第i次的更新,則第i次更新的頻率f(i)表示為:

其中fb為開始的頻率,fr是最終運行的頻率,α是曲線的伸縮係數,一般可以取3-5之間的常數。
比如,啟動加速,開始頻率為400Hz,運行頻率為5KHz。
停止減速,開始頻率為5KHz,停止頻率為400Hz,
加減速的時間均為1s,按10ms的時間間隔更新頻率,總共更新100次,α取5。
則可以繪製以下的加減速曲線:

編程
通過以下步驟實現實現步進電機的S曲線的加減速控制:
- 配置1ms的定時器以及1ms的中斷程序
- 在中斷程序中對加減速的頻率更新次數i進行計數
- 配置產生步進電機驅動信號的PWM模塊,設置PWM的定時中斷以及中斷程序
- 在PWM的定時中斷程序中,計算當前更新次數對應的頻率,並按出來的頻率更新PWM的頻率以及占空比
- 在PWM的定時中斷程序中,計算步進電機運行的步數,如果達到設置的步數減去停止的S曲線減速運行所設置的步數,則開始減速運行。
- 同時檢測外部輸入,如果有需要停止運行的輸入條件,則開始減速運行。
整個加減速控制過程的難點在於:
- 步進電機的計步以及頻率更新需要在每一個PWM中斷中進行。
- 步進電機的運行頻率最高到40KHz,這種頻率下,PWM的定時中斷周期達到了25us,PWM定時器中斷程序運行總時間盡量小,根據經驗至少小於中斷周期的30%,即7.5us。一旦超過這個數值,導致所有中斷程序(包括PWM定時中斷程序)漏運行,基本主程序無法運行,導致整個控制器假死現象。
- 根據S曲線的公司是一個複雜的非線性的指數浮點數運算,需要耗費大量的時間,直接調用C語言的庫函數計算這一數值可能耗費幾十上百毫秒。
為了解決S曲線的運算時間問題,基於STM32F103,我採用了查表法,具體步驟如下:
1. 將α值定義5,

的取值範圍為-5~5之間。
2. 在整個加減速過程中,表達式

在取值範圍-5~5內均勻取1024個數值,得到數值表。
3. 定義一個unsigned short型有1024個元素的const類型的數組,用於存儲數值表。
4. Const數組存儲在內部的flash,數值表共佔用2048位元組。
STM32F103RTC6共256K,程序組和設置參數佔用48K,bootloader程序佔用了8K,遠程升級空間佔用了100K,目前應用程序只用到40K左右。
剩餘60K左右的空間,騰出2K的空間來存儲數值表,有空間,就是這麼任性。
5. 在中斷程序中,根據總的更新次數以及當前的更新計數值,計算

值,再映射到0-1023的數值有的索引值,通過索引獲取數值。
6. 需要注意的是stm32f103不支持浮點數的運算,所以對於浮點數的運算,需要換算成乘以一個數再除以另一個數,比如*α,需要轉變為*65535/13107。
下面一段代碼是根據更新的計數值獲取頻率的函數:
U16 fnMC_GetFreq(U16 n, U16 halftn, U16 alpha, U16 minfreq, U16 maxfreq){//alpha=alpha * 4096 signed int udataA; signed short uiDataA; U16 uiRes; U32 uwData; udataA = (signed int)alpha * (signed int)n; udataA = (signed int)udataA / halftn; if(udataA > 32767){ udataA = 32767; } uiDataA = (signed short)alpha - (signed short)udataA; uiDataA = (signed short)4 * 4096 - uiDataA; if(uiDataA < 0){ uiDataA = 0; } uiRes = (U16)uiDataA; uiRes = uiRes / 32;//*1023/8/4096 if(uiRes > 1023){ uiRes = 1023; } udataA = (signed int)(maxfreq - minfreq) * g_mc_uchExp[uiRes]; udataA = udataA / 65535; uiDataA = (signed int)udataA; uiDataA += minfreq; if(uiDataA < 200){ uiDataA = 200; } return(uiDataA); }
下面一段代碼是產生步進電機控制信號的PWM周期中斷程序:
int data; U16 freq; STRMotorRegs *motor; motor = &g_motor_regs[0]; MOTOR_A_CLEARINT(); motor->steps ++; data = (int)MOTOR_A_STEPS_GET(); if(motor->direction == 0) { data = data + 1; } else { data = data - 1; } MOTOR_A_STEPS_SET(data); freq = motor->runfrequency; if(motor->runstate == MOTOR_RUN_STATE_INC){ if(motor->runtimer >= motor->starttime){ motor->runstate = MOTOR_RUN_STATE_IDLE; }else{ freq = fnMC_GetFreq(motor->runtimer, motor->halfstarttime, motor->alpha, motor->startfreq, motor->runfrequency);//U16 n,U16 halftn,U16 alpha,U16 maxfreq,U16 minfreq) } motor->runsnapfreq = freq; }else if(motor->runstate == MOTOR_RUN_STATE_IDLE){ if(motor->totalstep <= (motor->steps + motor->stopremainstep)){ motor->runstate = MOTOR_RUN_STATE_DEC; motor->runtimer = 0; } motor->runsnapfreq = freq; }else{ if(motor->runtimer >= motor->stoptime){ freq = motor->stopfreq; }else{ freq = fnMC_GetFreq(motor->runtimer, motor->halfstoptime, motor->alpha, motor->runsnapfreq, motor->stopfreq);//U16 n,U16 halftn,U16 alpha,U16 maxfreq,U16 minfreq) } } if(motor->steps >= motor->totalstep) { motor->starting = FALSE; } if(FALSE == motor->starting) { MOTOR_A_DISABLE(); }else{ motor->curfrequency = freq; fnMT_Cal_MotorA_TimeConf(); }
實踐
下面是生成S曲線數值表、控制步進電機啟動、停止的視頻,從視頻上可以明顯看到啟動時慢加速->快加速->慢加速的過程,以及停止時慢減速->快減速->慢減速的過程。
原創文章,作者:投稿專員,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/202112.html