このISRルーチンはどのように機能しますか?

私は現時点でステッピングモーターのステップ信号を書き込もうとしていて、最近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のいずれかの状態で増分されます。

クイックデバッグでは、変数が希望する値まで増加することを示していますが、実際にはわかりません。

非常に単純なものが欠けているのはわかります。

1
ru de

4 答え

これら3つの変数は静的です。つまり、それらは一度だけ初期化されます。

// 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;

このコードに従えば、割り込みから次の割り込みまで状態を保つために使用されていることがわかります。

3
追加された
ああ……神よ、あなたは正直だ。
追加された 著者 Lamda,

これら3つの変数は静的です。つまり、それらは一度だけ初期化されます。

// 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;

このコードに従えば、割り込みから次の割り込みまで状態を保つために使用されていることがわかります。

3
追加された
ああ……神よ、あなたは正直だ。
追加された 著者 Lamda,

static が関数のローカル変数に適用されたときの動作を理解する必要があります。

static unsigned int step_count = 0; は、関数 step_count への最初のアクセスが0に設定されることを意味します。これは、関数に毎回設定されるわけではありません。

static は、スタック変数ではないことを意味します。グローバル変数と同じメモリ空間にありますが、宣言する関数内でしかアクセスできない点が異なります。

2
追加された
ええと..とにかく私はそれをもう少し慎重にそれを読む必要がありました:)
追加された 著者 Lamda,

static が関数のローカル変数に適用されたときの動作を理解する必要があります。

static unsigned int step_count = 0; は、関数 step_count への最初のアクセスが0に設定されることを意味します。これは、関数に毎回設定されるわけではありません。

static は、スタック変数ではないことを意味します。グローバル変数と同じメモリ空間にありますが、宣言する関数内でしかアクセスできない点が異なります。

2
追加された
ええと..とにかく私はそれをもう少し慎重にそれを読む必要がありました:)
追加された 著者 Lamda,