步進電機是將電脈沖信號轉變為角位移或線位移的開環控制電機,是現代數字程序控制系統中的主要執行元件,應用極為廣泛。。在非超載的情況下,電機的轉速、停止的位置只取決于脈沖信號的頻率和脈沖數,而不受負載變化的影響,當步進驅動器接收到一個脈沖信號,它就驅動步進電機按設定的方向轉動一個固定的角度,稱為“步距角”,它的旋轉是以固定的角度一步一步運行的。可以通過控制脈沖個數來控制角位移量,從而達到準確定位的目的;同時可以通過控制脈沖頻率來控制電機轉動的速度和加速度,從而達到調速的目的。
步進電機是一種感應電機,它的工作原理是利用電子電路,將直流電變成分時供電的,多相時序控制電流,用這種電流為步進電機供電,步進電機才能正常工作,驅動器就是為步進電機分時供電的,多相時序控制器。
步進電機S型曲線加減速算法與實現
S型曲線的的方程,在[-5,5]的圖形如下圖所示:
如要將此曲線應用在步進電機的加、減速過程中,需要將方程在XY坐標系進行平移,同時對曲線進行拉升變化:
其中的A分量在y方向進行平移,B分量在y方向進行拉伸,ax+b分量在x方向進行平移和拉伸。
項目中加速過程:從5600Hz加速到64000Hz,采用4細分。輸出比較模塊所用的定時器驅動頻率為10M,采用1000個點進行加速處理。最終根據項目的需要,在加速過程中采用的曲線方程為:
。
其中的Fcurrent為length(1000)個點中的單個頻率值。Fmin起始頻率為5600; Fmax為最大頻率64000; -flexible*(i - num)/num是對S型曲線進行拉伸變化,其中flexible代表S曲線區間(越大代表壓縮的最厲害,中間(x坐標0點周圍)加速度越大;越小越接近勻加速。理想的S曲線的取值為4-6),i是在循環計算過程中的索引,從0開始,num為 length/2 大小(這樣可以使得S曲線對稱)。在項目中i的區間[0,1000), num=1000/2=500。這些參數均可以修改。提供的計算接口如下。
對應的計算接口code:
/* calculate the Period and Freq array value, fill the Period value into the Period register during the timer interrupt.
*calculate the acceleration procedure , a totally 1000 elements array.
* parameter fre[]: point to the array that keeps the freq value.
* period[]: point to the array that keeps the timer period value.
* len: the procedure of acceleration length.it is best thing to set the float number, some compile software maybe transfer error if set it as a int
* fre_max: maximum speed, frequency vale.
* fre_min: start minimum speed, frequency vale. mind : 10000000/65535 = 152, so fre_min can‘t less than 152.
* flexible: flexible value. adjust the S curves
*/
void CalculateSModelLine(float fre[], unsigned short period[], float len, float fre_max, float fre_min, float flexible)
{
int i=0;
float deno ;
float melo ;
float delt = fre_max-fre_min;
for(; i《len; i++)
{
melo = flexible * (i-len/2) / (len/2);
deno = 1.0 / (1 + expf(-melo)); //expf is a library function of exponential(e)
fre[i] = delt * deno + fre_min;
period[i] = (unsigned short)(10000000.0 / fre[i]); // 10000000 is the timer driver frequency
}
return ;
}
// start move motor
void StartPWM()
{
DriverMotorFlag = TRUE;
Index = 0;
MOTOR_EN_DISABLE = ENABLE;
OpenOC4(OC_ON | OC_TIMER_MODE16 | OC_TIMER3_SRC | OC_PWM_FAULT_PIN_DISABLE, 0, 0);
// map rc13 to oc4 output
RPC13R = 11;
// 50 percent duty
OC4RS = OC_PERIOD_MIN / 2;
OpenTimer3(T3_ON | T3_PS_1_8, OC_PERIOD_MIN);
INTSetVectorPriority(INT_TIMER_3_VECTOR, INT_PRIORITY_LEVEL_6);
INTSetVectorSubPriority(INT_TIMER_3_VECTOR, INT_SUB_PRIORITY_LEVEL_1);
EnableIntT3;
}
//stop motor, hereis no deceleration
void StopPWM()
{
DriverMotorFlag = FALSE;
Index = 0;
MOTOR_EN_DISABLE = DISENABLE;
OpenOC4(OC_OFF | OC_TIMER_MODE16 | OC_TIMER3_SRC | OC_PWM_FAULT_PIN_DISABLE, 0, 0);
// map rc13 to oc4 output
RPC13R = 0;
PORTCbits.RC13 = 0;
CloseTimer3();
DisableIntT3;
}
//change the timer Period value in the correspond timer rather than the other place, Or the motor will be stalled occasionally.
// 剛開始我在另外的一個定時器中斷中每隔1ms改變 應用在OC模塊的timer3 的Period值,結構偶發的造成電機在加速過程中堵轉。其實應該是在timer3的中斷中修改。
static unsigned short CountForAcc = 0;
void __ISR(_TIMER_3_VECTOR, ipl6) Timer3OutHandler(void)
{
// clear the interrupt flag, or the interrupt will not occur again.
mT3ClearIntFlag();
if(CountForAcc++ 》 2) // here can adjust the totally time of acceleration
{
CountForAcc = 0;
//if(DriverMotorFlag == TRUE && PR3 》 OC_PERIOD_MAX + SPEED_STEP)
if(DriverMotorFlag == TRUE && Index 《 ACC_TIMES)
{
PR3 = Period[Index++];
OC4RS = PR3 / 2;
}
}
}
通過CalculateSModelLine接口得到如下不同的幾條加速曲線:
黃色:CalculateSModelLine(Freq, Period, 1000, 56000, 16000, 4);
橙色:CalculateSModelLine(Freq, Period, 1000, 64000, 500, 8);
藍色:CalculateSModelLine(Freq, Period, 1000, 64000, 500, 15);
灰色:CalculateSModelLine(Freq, Period, 1000, 40000, 500, 5);
最后可以估算加速過程的時間和角位移,以橙色曲線為例:CalculateSModelLine(Freq, Period, 1000, 64000, 500, 8)為例(假設在中斷中沒有 if(CountForAcc++ 》 2) 條件限制):
時間:Period第一個點的值為10000000/500 = 20000,最后也點的值 10000000/64000=156,平均值為10000左右,timer中斷的平均時間Tn=10000/10000000=1ms, 1000個點,總時間為1s,當然,起始頻率大加速時間就越短,比如Fmin=16000Hz,Fmax=64000,則40ms左右即可完成加速過程。
角位移:1.8(單步) * 1000(步數) / 4(細分)= 450°
上述為加速過程,減速同樣的道理,只要將方程改為:
可以得到減速曲線如下所示:
評論