私は現時点でステッピングモーターのステップ信号を書き込もうとしていて、最近atmelがこれを書いていることを知りましたアプリケーションノート、
そしてその目的でいくつかのコードを提供しました。私が私のモーターに提供しなければならない信号は、それらが提供する4ピン信号よりもむしろ信号の周波数が速度を決定するパルス変調信号です。コードは github (リンク)。
しかし、私は現在、モーターのすべての段階(停止、加速、運転、減速)を制御するISRルーチンについて質問しています。
より具体的には、状態の変更を担当するstep_countをどのように追跡するのか。
#pragma vector=TIMER1_COMPA_vect
__interrupt void speed_cntr_TIMER1_COMPA_interrupt( void )
{
//Holds next delay period.
unsigned int new_step_delay;
//Remember the last step delay used when accelrating.
static int last_accel_delay;
//Counting steps when moving.
static unsigned int step_count = 0;
//Keep track of remainder from new_step-delay calculation to incrase accurancy
static unsigned int rest = 0;
OCR1A = srd.step_delay;
switch(srd.run_state) {
case STOP:
step_count = 0;
rest = 0;
//Stop Timer/Counter 1.
TCCR1B &= ~((1<= srd.decel_start) {
srd.accel_count = srd.decel_val;
srd.run_state = DECEL;
}
//Chech if we hitted max speed.
else if(new_step_delay <= srd.min_delay) {
last_accel_delay = new_step_delay;
new_step_delay = srd.min_delay;
rest = 0;
srd.run_state = RUN;
}
break;
case RUN:
sm_driver_StepCounter(srd.dir);
step_count++;
new_step_delay = srd.min_delay;
//Chech if we should start decelration.
if(step_count >= srd.decel_start) {
srd.accel_count = srd.decel_val;
//Start decelration with same delay as accel ended with.
new_step_delay = last_accel_delay;
srd.run_state = DECEL;
}
break;
case DECEL:
sm_driver_StepCounter(srd.dir);
step_count++;
srd.accel_count++;
new_step_delay = srd.step_delay - (((2 * (long)srd.step_delay) + rest)/(4 * srd.accel_count + 1));
rest = ((2 * (long)srd.step_delay)+rest)%(4 * srd.accel_count + 1);
//Check if we at last step
if(srd.accel_count >= 0){
srd.run_state = STOP;
}
break;
}
srd.step_delay = new_step_delay;
}
私には見えますが、ISRの開始時にstep_countがゼロに設定され、ACCEL、RUN、DECELのいずれかの状態で増分されます。
クイックデバッグでは、変数が希望する値まで増加することを示していますが、実際にはわかりません。
非常に単純なものが欠けているのはわかります。