「天文屋のためのマイコン入門」タイマープログラムの改良
前回出したタイマーのプログラムですが、ちょっと改良してみましょう。
まず、タイマーレジスタTMR0に-30を代入してカウントアップしていますが、単純に考えてこの値が大きいほど精度が良くなると想像できます。
値が30ということは、最大1/30の誤差を伴います。ただ、大きくすると言っても、8ビットレジスタなので、最大で255までです。それを考慮して、計算する必要があります。
プリスケーラーの分周比を現在の1/256から8倍の1/32にしてみたらどうでしょう。
この場合、TMR0に入力されるクロックの周波数は
31250÷4÷32 = 244Hz
したがって、TMR0レジスタに-244を代入してカウントアップすることにします。
分周比を1/32にするには、OPTION_REGのビット0とビット1を0にクリアします。したがって、以下の2行を初期化部に追加します。
BCF 81h,1
BCF 81h,0
もう一つの改良点
TMR0レジスタが0になったかどうかの判定ですが、TMR0レジスタの値をワーキングレジスタに転送し、ゼロフラグで判定しています。しかし、その間にもTMR0レジスタはカウントアップしていますので、0を読みすごしてしまう不安が生じます。
ただ、この不安はあたりません。なぜなら、TMR0に入力されるクロックは、命令のクロックを128分周しています。つまり、TMR0が0から1にカウントアップしている間にマイコンは、128命令も実行してしまいます。これなら読みすごしてしまうことはないでしょう。
ただ、後で説明しますが、割込みというのが発生するとプログラムが中断され、その間にもTMR0がカウントアップするので、まったく可能性がないともいえません。
そこで、もう少しましな方法を採用します。
実は、TMR0がオーバーフローすると、セットされるフラグがあるのです。INTCONというレジスタ(0bh番地)のビット2がそうです。ですから、このビットでオーバーフローを判定します。このビットをオーバーフローフラグといいます。
プログラムは以下のようになります。
まず、オーバーフローフラグを0にクリアします。なぜならオーバーフローフラグは自動ではクリアされず、プログラムでクリアする必要があるためです。
BCF 0bh,2 ;オーバーフローフラグクリア
16進数で先頭がアルファベットの場合は先頭に0をつけます。
次に、オーバーフローフラグを判定し、セットされているなら、つまりオーバーフローが発生しているなら、次のGOTO命令をスキップして、サブルーチンを終了します。
BTFSS 0bh,2 ;オーバーフローしたらスキップ
GOTO Wait1s_LOOP ;オーバーフローしないならループ
プログラムの全部を掲載します。
さて、この1秒待つサブルーチンですが、これは正確な1秒ではありません。確かに、TMR0は1秒でオーバーフローしますが、このサブルーチンを呼び出して処理する命令実行時間がかかりますので、1秒より長くなります。これをオーバーヘッドといいます。
正確に1秒にしたいなら、このオーバーヘッドも考慮してTMR0の初期値を決定する必要がありますが、今後説明する「割込み」という機構を利用する方が懸命です。
まとめ
これで一通り、タイマーの説明をしましたが、関連するレジスタが3つ出てきました。これを最後にまとめておきます。
TMR0 1h番地
タイマー0レジスタ 0から255までカウントアップしている
OPTION_REG 81h番地(バンク1の1h番地)
TMR0の入力クロック源を選択したり、プリスケーラーの分周比を選択するレジスタ
INTCON 0bh番地
TMR0のオーバーフローフラグがあるレジスタ
| 固定リンク
コメント