フリーランタイマで割り込みを起こす

マイコンであるソフトウェアを動かすのにタイマが必要という話があって、

コンペアマッチ機能を備えたフリーランタイマがあればよいという話で、

その説明で僕はすぐに納得したのだが、チームの他のメンバーは理解できなくて、

そういうタイマの使い方ってあまり一般的ではないのか? と知る。

確かにそういう動かし方のできないタイマというのは存在するらしい。


マイコンのタイマの使い方もいろいろである。

  1. 一定周期で割り込みを発生させる or 出力を変化させる
  2. 一定時間経過後に割り込みを発生させる
  3. タイマ起動からの経過時間をカウントする
  4. カウントが設定値に達したら割り込みを発生させる or 出力を変化させる

他にもいろいろ使い方はあると思いますけどね。

出力を変化させるというのはPWM出力などで使うやつですね。

今回言っているのはタイマを4.の使い方をする話である。


1.のようなタイマの使い方をする場合、タイマのカウント数を戻す仕組みが付いていることが一般的である。

例えば、1μsに1カウントアップするタイマがあったとして、

10000に達すると0に戻してタイマ動作を継続させつつ、割り込みを発生させる。

こう設定するとタイマの設定を触らずとも10msに1回の割り込みが発生し続ける。

自動的にタイマを戻す仕組みは割り込みの場合は必須とも言えないのだが、

タイマを使って周期出力を作る場合はタイマ自身がカウント数を戻す仕組みは必須である。


2.のようなタイマの使い方も1.とあまり変わらない。

5000に達するとタイマを停止して割り込みを発生させる設定をしてから

タイマの値を0に戻して、タイマを起動すると、5ms後に1回割り込みが入る。

キッチンタイマーはそういう使い方ですよね。

3.のフリーランカウンターはそれだけでも経過時間を測定するために使うことができる。

ストップウォッチとか時計のイメージだな。

時計は12時を過ぎると0に戻るように、フリーランカウンターもオーバーフローすれば0に戻る点に注意して使う。


で、4.は設定値に達してもタイマのカウントは変えずに、割り込みや出力変化を発生させるというもの。

例えば、1.のタイプのタイマと組み合わせてPWM出力に使われる。

タイマの値が4000に達するとLo出力、10000に達するとHi出力して0に戻す。

こうすると10ms周期でHi出力4ms、Lo出力6ms、デューティー比40%のPWM出力が作れる。

このように設定値を2つ持って、それぞれに動作を決められるのは、典型的なマイコンのタイマではないか。


そして、3.で書いたフリーランタイマとの組み合わせでも使われる。

例えば5ms→10ms→8ms→のような様々な間隔で割り込みを発生させる場合、

処理開始時のフリーランカウンターの値が123456だったとして、

これに5000加えた128456を設定値にして割り込み発生とする。

すると5ms後に割り込みが発生するので、処理の中で設定値を138456にする。

すると10ms後に割り込みが発生するので、処理の中で設定値を146456にする。

すると8ms後に割り込みが発生するといった具合である。

2.のタイプのタイマを都度仕掛けても同じようなことはできるのだが、

割り込み処理の間、タイマが止まると割り込みの間隔が少しズレてしまう。

フリーランカウンタでタイマ割り込みを発生させる方法を使っているのは、

割り込み間隔がだんだんズレていくことを防ぐためだろうな。


冒頭に「そういう動かし方のできないタイマというのは存在する」と書いた。

この指摘の後に調べて気づいたのだが、ARM Cortex-MのSysTickタイマは4.の使い方ができない。

LOADレジスタの設定値からカウントを開始し、カウント値の値が0になれば、割り込みを発生させて、LOADレジスタに戻す。

1.のタイマとして0→設定値でカウントアップするタイマを例示したが、

設定値(LOADレジスタ)→0のカウントダウンで同じことをやっている。

2.のタイマとしてはLOADレジスタを設定→タイマ起動→LOADレジスタを0にするとすれば、

時間経過後に割り込みを発生、カウント値は0で停止で1回限りのタイマになる。

(SysTickタイマをそういう使い方する人はあまりいないと思うけど)


3.のタイマとしては、LOADレジスタに最大値(例えば0xFFFFFF)を設定して、

割り込み無効でタイマを起動すると、0xFFFFFFからカウントダウンして、

0に達したら自動的に0xFFFFFFに戻って再びカウントダウンする。

減少方向ではあるが、これもフリーランタイマではある。

しかし、ここに設定値で割り込みを発生させる機能を加えることはできない。

タイマが0に達したタイミングでしか割り込みを発生できないからである。


シンプルなタイマとしてはこれでいいんだろうけどね。

一方で割り込み用途に限れば4.の機能を備えたフリーランタイマがもっとも汎用的と言える。

定周期で割り込みを発生させるというのは、

割り込みが発生するごとに設定値に一定値加算するという方法で実現できる。

一定時間経過後に割り込みを発生させるというのも、

現在地+設定時間に応じたカウント数を設定値にして割り込みを発生させればよい。

もっともマイコンのタイマとしてはPWM出力のような用途もあり、そのような用途には適しませんが。

フリーランタイマは都度設定値を再設定するのが前提ですからね。


というわけで、そんなのも知らんかったのかと簡単に言える話ではないが、

タイマの使い方の1つとして書かれているよねという話だった。

任意の設定値でイベントを発生させるのはPWMがイメージしやすいが、

一方でPWMとフリーランタイマの組み合わせは一般的にはないので、そこはわかりにくいかも。