News center
新聞中心
2021-03-25??瀏覽次數:9671
步進電機是將電脈沖信號轉換成角位移或線位移的開環控制電機。它是現代數字程控系統的主要執行部件,應用廣泛。在非過載情況下,電機的轉速和停止位置只取決于脈沖信號的頻率和脈沖數,不受負載變化的影響。步進驅動器接收到脈沖信號后,驅動步進電機在設定的方向旋轉一個固定的角度,稱為“步角”,其旋轉以固定的角度步進運行。角位移可以通過控制脈沖數來控制,從而達到精確定位的目的;同時,可以通過控制脈沖頻率來控制電機的速度和加速度,從而達到調速的目的。
步進電機是感應電機的一種。其工作原理是利用電子電路將直流電轉換成分時供電和多相定時控制電流。只有用這個電流給步進電機供電,步進電機才能正常工作。驅動器是一個多相定時控制器,分時向步進電機供電。
步進電機S型曲線加減速算法與實現
s型曲線方程
,在[-5,5]圖形中如下圖所示:
如果想把這條曲線應用到步進電機的加減速過程中,需要在XY坐標系中平移方程,同時拉起曲線:
其中a分量在y方向平移,b分量在y方向拉伸,ax b分量在x方向平移拉伸。
項目中的加速過程:從5600Hz加速到64000Hz,采用4細分。輸出比較模塊中使用的定時器驅動頻率為10M,1000點用于加速處理。后,根據項目需要,加速過程中采用的曲線方程為:
其中Fcurrent是長度為(1000)點的單個頻率值。Fmin啟動頻率為5600;Fmax為頻率64000;-flexible*(i-num)/num為S形曲線的拉伸變化,其中flexible表示S形曲線的區間(越大壓縮越劇烈,中間加速度越大(X坐標0點附近);越小越接近勻加速。理想S曲線的值是4-6),I是循環計算過程中的指標,num是從0開始的長度/2(可以使S曲線對稱)。在項目中I的區間[0,1000]內,num=1000/2=500。這些參數可以修改。提供的計算接口如下。
相應計算接口的代碼:
/*計算周期和頻率陣列值,在定時器中斷期間將周期值填入周期寄存器。
*計算acceleraTIon過程,總共1000個元素的數組。
*參數fre[]:指向保存freq值的數組。
* period[]:指向保存TImer period值的數組。
* len:加速長度的程序,好設置浮點數,有些編譯軟件可能會轉移
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);