« インプットキャプチャ | トップページ | なのでね.... »

2021年5月19日 (水)

長周期かつ高時間分解能なインプットキャプチャ

で、16ビットを超えるタイマーイベント、
インプットキャプチャ部門だけど。


これ、まあ。
ペリフェラルの機能として
一つのタイマーのオーバーフローを
別のカウンターの入力クロックに接続、
なんて設定があるので、これを使えば
良さそうなもんだけど。

キャプチャとオーバーフローが
重なったときにそれぞれの
レジスタが、正しい値で
整合しているという保証はない。

内部ロジックで、キャプチャの
ロジックが接続されているわけでなく、
信号をそれぞれのタイマーに
個別に 入力する関係で、
こういうクリティカルパスが
発生する。


まあ、ごくまれにしか発生しないけど、
それゆえ、検出と対策が難しい。

まあ、素直に32ビットタイマ使っとけ、
という案件ではあるのだが....



------

なので、これも、コンペアマッチと
同様にソフトウエアで上位ビットを
あれこれやって、機能を実現してみる。


タイムアウトに使っている
インターバルカウンタの値を、
カウンタの上位データ
(の指標)として使う。


当然、そのまま上位データ
としては使えないので一工夫。

データとして使うのは
あくまでタイマーのキャプチャ
レジスタの値。

------

説明しやすくするために
インプットキャプチャは1MHzで
カウントしていて、タイムアウト用
の別タイマは1msecインターバルで
動いているとしようか。

とあるタイミングでキャプチャされた
値と前回キャプチャされた
値の差がNとなった場合、
この時の真のパルスの間隔は、

N+65536*M(usec)

となる(Mは0~)

値として分かるのはNだけなので、
ここからMを推測する。

ここで、1msecインターバルで
ソフトウエアカウンタを回し、
1msecでのパルス間隔も
(大まかに)計測する。

こっちは、C(msec)としようか。



この2つのデータを合わせ、元のMを計算する。

N + 65536 * M ≒ C * 1000

なので、

M ≒ (C * 1000 - N) / 65536

と変形して、Mの概算値を求める。
計測されたCの値は、正確ではないけれど、
概ね整数値の近くに寄ってくる。

整数計算で四捨五入すれば、Mが求まるので

M = (C*1000 - N + 32768) / 65536

で、Mが確定し、

N + 65536 * M

で目的のインターバル(usec)が求められる。

タイムアウトのインターバルは、
元のクロックやオーバーフローから
一桁くらい離れていれば問題なく
機能するはず。


これで、16ビットタイマーで
長ビットでのインプットキャプチャが
実現できる。

ちょっとややこしいけれど、
この方法を使うようになって、
タイマー周りのクリティカルパスは
大体回避できるようになったと思う。


コード例としては

#define TIMEOUT 1000

unsigned long interval;   //  計測した時間間隔
int timeout;       // タイムアウトカウンタ


void SysTick_Handler(void){ //  1msecインターバル

  if (timeout > 0 ){
    timeout--;
    if (timeout == 0){
      interval = 0xffffffff;  // タイムアウト
      }
    }
  }
}


void TIM2_IRQHandler(void) {  // ch1でインプットキャプチャ

  static unsigned short last;
  unsigned short us;


  if (TIM2->SR & (1 << 1)) {  //インプットキャプチャ

    us = TIM2->CCR1;

    if (timeout > 0){
       interval = ( (unsigned long)(32768L + (TIMEOUT - timeout)  * 1000 - ((us - last) & 0xffff) ) & 0xffff0000) + (unsigned long)(us - last);
    }

    last = us;     // 今回の値を保存
    timeout = TIMEOUT;   // タイムアウト初期化
  }
}



これもそうだけど、
こういったプログラム、
何をやろうとしているのか、
コードだけから読み取るのは
かなり難しいね...


| |

« インプットキャプチャ | トップページ | なのでね.... »

コメント

コメントを書く



(ウェブ上には掲載しません)




« インプットキャプチャ | トップページ | なのでね.... »