PIC12F1822でTimer0を使ってみる。
いつまでも人様のコードを拝借するばかりでもつまらないので、データ・シートを読むだけで出来るかどうか試してみた。
データ・シートで「Timer0」を簡易検索する。
8ビットのカウンターで8ビットのプリスケーラを備えていることがわかる。
ついでに、Timer1やTimer2もあることも。
Timer0についてどこに書かれているかわかるので、
しおりの該当するところをクリックすると、
ちゃんとジャンプして表示してくれる。
まずはTimer0そのもののカウント値はTMR0というレジスターに書かれていることがわかる。
(1)タイマーとしての使い方とカウンターとしての使い方があるということだがここではタイマーとして使う。
(2)そのモードはTMR0CSで設定する。
(3)TMR0に値を書き込むと2サイクル分遅れる。
というようなことが書かれている。
基本的にはレジスターの設定を追っていくのがわかりやすい気がする。
「TMR0CS」を検索する。
大概次のページあたりに載っている。
即座にMPLAB X IDEでコードを追加する。
次はプリスケーラーの値を決めるが、これは「PSA」と「PS」で設定する。
さっきの「TMR0CS」と同じレジスターなので、同じところに載っている。
ここでは8MHzの内部クロックを使うことにして以下のように考えてみた。
8000000 = 4 × 64 × 250 × 125
4 : Fosc/4
64 : Prescale
8 : TMR0 ( 256 – 250 + 2 )
125 : Loop
TMR0に設定する値は、設定すること自体がクロックを消費するのでその分を2加えて大きくする。
大きくするとカウント数は減るので割り込みの間隔は短くなる。
ただ、このあたりのきっちりした決め方がまだ良くわかっていないのは今後の課題だ。
具体的に言うと、MPLAB X IDEのSimulatorのStopwatchで計測したときにぴったり1秒にできない。
この例では 1.00088 sとなる。
ともかく、これもすぐにコードとして書き込む。
いよいよ肝心の割り込みの設定だ。
(1)Timer0の割り込みがかかると「TMR0IF」がセットされる。
(2)Timer0による割り込みは「TMR0IE」を設定することで使用可能となる。
これらはINTCONレジスタの中にある。
ちなみに「GIE」もアクティブに設定しないといけないが、ここまでのところでは登場していないので、はじめてだったら飛ばしてるかも。
当然コードとして書き込む。
あとはinterruptに適当な名前をつけてこんな感じ。
なんとか、約1秒ごとにLEDがチカって光るようにできた。
Interrupt関数内は軽くしないといけないとどこかで読んだ。
本当は、こんな処理は関数化して外へ出さなければ、同時に他の割り込みがかかったときにトラブルの元になるからだ。
参考
「PIC16F1827 Timer2」