PIC12F629 はフラッシュタイプなので、何度も書き直しができる。これは失敗の多い初心者にはとてもうれしい。紫外線消去タイプでもいいのだが、プログラムを修正しては書き込んでのテストを頻繁に繰り返すには消去にかかる時間がとても長く感じる。実際に使ってみると消去の必要がないフラッシュタイプの方が断然使いやすい。
PIC12F629 タイマ割り込み、アナログコンパレータ等が使える。スタックレベルが 8 段あるのもうれしい。 DIP タイプなら 1 個 140 円ぐらいと安価なのも魅力だ。新たな PIC ライタでの書き込み環境が整ったのでまずは互換モードで動かす勉強をしてみた。
機能が増えているので各 I/O ピンの働きを決めるための作業が初心者にはわかりにくい。インターネットで検索しても使用例がとても少ない。またデータシートも英文なのでなかなか理解しにくい。
まず最初につまずいたのが BANDGAP Value なる言葉。工場出荷時に内部発振周波数の校正値 OSCCAL Value とともに BANDGAP Value なるものが書き込まれていて、この二つの値を読み出して保存する必要がある。当然 OTP と違ってプログラムを書き込むと消えてしまうからだ。
データシートを調べた結果、ブラウンアウトリセットとかパワーオンリセット等で使う電圧の敷居値を校正する値のようである。 BANDGAP Value は CONFIGURATION WORDの bit13 と bit12 に記録されている。 OSCCAL Value は プログラムエリアの最終番地 0x3FF に記録されている。
OSCCAL Value は内部発振回路を使うときの発振周波数の校正値で、この値はプログラムメモリの最終番地(0x3FF)に記録されている。今回の個体ではプログラムコードの最後に 349C と表示されている。この値も BANDGAP Value とともに記録しておく。どちらもプログラムを書き込むと上書きされてしまう。特に OSCCAL Value は内部発振クロックの精度に影響してくるので大切である。はじめ OSCCAL レジスタにこの校正値をうまく書き込むことができず、 4MHz とは大きくかけ離れた発振周波数となってしまった。
そこで LED が点滅するだけのごく簡単なプログラムで内部発振回路がきちんと校正されているかを試してみた。 それが 629test.asm (テキスト形式) プログラム。 GP0 につないだ LED が 0.5 秒間隔で点滅を繰り返す。
PIC12C509A ではプログラムを実行すると、まず最終番地の値を W レジスタにセットして戻り、先頭からプログラムが実行される。そこでプログラムのはじめに movwf OSCCAL と記述するだけで、発振周波数校正値は OSCCAL レジスタに格納された。 PIC12F629 ではプログラムの中でプログラムエリアの最終番地を読みに行って、その値を W レジスタに格納する作業もプログラムで記述しなければならない。その後 movwf OSCCAL として PIC12C509A の時と同様発振周波数校正値を OSCCAL レジスタに保存する。
call | 0x3ff | ||
movwf | OSCCAL | ||
: | |||
: | |||
: | |||
org | 0x3ff | ||
retlw | 0x9c | ;とりあえず手元の個体の校正値をセット |
こうすることでプログラムは正常に動くようになる。ライタソフトに HEX ファイルを読み込むと、あらかじめセットした値(0x9c)が 0x3FF 番地に書き込まれるが、プログラムを書き込む PIC の校正値を 3xFF 番地に上書きしてから PIC に書き込めば正しい発振周波数でプログラムが動作する。わかってしまえば簡単だが、プログラムがきちんとした周波数で動かなくてこのことに気がつくまでにかなりの時間を費やしてしまった。OSCCAL レジスタは 8bit の上位 6bit を使っている。 b'111111' が最高周波数で、 b'000000' が最低周波数となる。センター周波数は b'100000' 。従って校正値は 'FC' から '00' の範囲にあることがわかる。
PIC12F629 では割り込みがつかえたり、コンパレータを備えていたりと多機能なのだが、 PIC12C509A での命令とはやや異なり、どちらかというと PIC16F84A に近いと感じた。
CONFIG WORD は PIC への書き込み時にライタソフトで設定することもできるが、プログラムの中にあらかじめ記述しておくこともできる。たとえば内蔵発振回路を使う記述では PIC12C509A の場合 _IntRC_OSC としたが PIC12F629 では _INTRC_OSC_NOCLKOUT とするなど、このあたりの設定も今までとは異なる。
とりあえず PIC12C509A 互換モードでの動作が確認できたので、これからは PIC12F629 の特徴を少しずつ生かした使い方を勉強していきたい。