2023年5月27日土曜日

PICマイコンのTimer1

 今回は8bit PICマイコンのTimer1についての話。

初期のPICマイコンにはTimer0という8bitのタイマーが1つだけ載ってました。
その後、PICマイコンの機能拡張として、16bitのTimer1が追加されたという経緯。

Timer0だけでも、割り込みをうまく使えば各種時間管理を行うことは可能ですが、
PICマイコンの基本方針はハードをうまく利用することでソフトの負担を軽減する事なので、
Timer1の追加実装は ありがたかったわけです。
特に私のようなハード屋にとっては。

さてここからが今回の本題。

Timer1が16bitのカウンターである旨は先に書きました。
しかしPICマイコンが8bitである以上、そのレジスターは1つというわけいきませんね。
なので、上位・下位の8bitレジスター2つで構成されているわけです。

そうなると、カウンター値を読むためには2つのレジスターにアクセスする必要があります。
さて、Timer1が動作中にカウンター値を読み込もうとしたら、どうなるでしょう?

2つのレジスターからの同時読み込みは当然無理ですから、
順番に読み込むことになります。
1つ目のレジスターを読み込んだ後、2つ目のレジスターを読み込む前に
カウンター値の桁上がりが発生してしまったら!!

もう少し解り易く、実例を書きますね。

カウンター値が0x01FFの時に、そのカウンター値を読み取ろうとします。

カウンター値 0x01FF = 上位が 0x01・下位が0xFF です。

まず、下位のカウンター値をレジスターから読み込みます。
  カウンター値 0x01FF
  読み込んだ下位値 0xFF

次に上位のカウンター値を読み込もうしますが、
ここでカウンターのインクリメントが発生し!
  カウンター値 0x0200

そして上位のカウンター値をレジスターから読み込みます。
  既に読み込み済みの下位値 0xFF
  読み込んだ上位値 0x02

すると、読み込んだカウンター値は
見かけ上0x02FFになってしまうのがご理解頂けますか?

本来ならば0x01FF もしくは 0x0200という値が得られなきゃならないところです。
しかし大幅に異なる値が取得できてしまう事態が起こるんですね。

もちろんこの問題はメーカーも把握しておりまして、
MicrochipとしてはTimer1へのアクセス時、
一時的なTimer1の停止を推奨しておりました。
しかし、外部信号入力によるカウンターとして使用していた場合、
一時的にTimer1を停止させるアクセス方は誤差要因になりうるわけです。

と、言うわけで!!

最近のTimer1は更に改良されております。

具体的には、上位カウンターのレジスターに、バッファーが噛むようになりました。
下位側のレジスターへアクセスすると、
それと同時に上位カウンター値がバッファーと同期するのです。
これは読み込み時のみならず、書き込み時も同様です。
これにより、先に書いたようなタイミング差による問題が解決されました。
なかなかにGJです、Microchipさん。

バッファーが追加? レジスターが増えたの?
いやいや そんなことは有りませぬ。
従来、上位カウンター値のアクセスレジスターが、
バッファーアクセス用のレジスターに変わっただけです。
なので見かけ上、実装されてるレジスターは以前と同様です。

ただ1点、アクセスする順番だけが規定されました。
読み込む際は下位->上位の順、
書き込む際は上位->下位の順です。
これを間違うとバッファーと上位カウンターの同期タイミングがおかしくなるので、
カウンター値がおかしくなってしまいます。

ともあれ、いちいちTimer1を停めなくてもカウンター値を読み書きできるのは
非常に便利ですね。

この改良型Timer1ですが、実装されたのは さほど古くありません。
少なくとも、一時期人気だったPIC16F193xシリーズには載っていません。
最近お気に入りのPIC16F18456には搭載されております。
ですので、この間にリリースされたPICマイコンを利用する際は、
個々に確認が必要と思われます。

0 件のコメント:

コメントを投稿