今回のプログラムでは“割り込み”を使う。割り込みの例を日常生活でいうと、こんな感じになるだろう。
「作業をしている」→「電話が鳴る」→「作業を中断して電話を取る」→「会話終了後作業に戻る」
この場合、「電話のベル」=「割り込み信号」、「電話の会話」=「割り込み作業」ということになる。自宅の電話はナンバーディスプレイがついていないのだが、ナンバーディスプレイ付電話や携帯電話なら以下のようなことも可能になる。
「原稿を書いている」→「電話が鳴る」→「ナンバーを見る」→(ヤバイ!編集部だ)→「聞こえない聞こえないと作業再開」
電話はこの場合副作業で、主作業ではない(編注:お、お前というやつは……)。
前回おこなった「LEDをピカピカ」はすべての処理を普通のプログラムで書いている関係で、ほとんどが時間待ちループというムダだらけのプログラムだったが、今回は割り込みを使ってみたい。
PICで割り込み処理を行う場合、ポイントはとりあえず2点ある。
(1)割り込みベクタは0004。リセットベクタが0000なので、リセット後ジャンプ命令でメインルーチンに飛ばす必要がある。
(2)割り込みのためには色々とビットセットが必要になる。
関係ない割り込み作業が入るのは困るので、割り込み許可というビットを立てないと割り込みは起こらない。また、どの割り込みが発生したかのフラグもチェックする必要がある(これが上でいう「ナンバーを見る」に相当する)が、今シリーズでは複数の割り込みを同時に扱わない。
能書きはこの辺にしてテストプログラムを書いてみよう。今回作るのは割り込みルーチン側の作業をおこなうプログラムだ。資料が英語だしと悩む人がいると思うので、まずPIC12F675ではなく、PIC12CE67Xの資料(これは日本語がある)を見てみよう。これには8ビットタイマーが1つある(PIC12F675には8ビットタイマーに加え、16ビットタイマーがある)。まず8ビットタイマーと割り込みをマスターしてしまおう。
PICのタイマーは加算タイプでオーバーフロー時に割り込みが発生する。8ビットなのでFFh→00hのタイミングで割り込み発生、というわけだ。加算のタイミングは内部クロックと外部クロックが選択できるが、余計な回路を付けたくないので今回は内部クロックを使う。
8ビットということは最大256クロック(4MHzクロックならば256マイクロ秒)とこれでは短すぎるので、内部クロックを分周するプリスケーラが用意されている(1:2〜1:256)。これで最大65536クロック(4MHzクロックならば65.5マイクロ秒)までカウントができる。精度を上げたければ分周比は可能な限り低く抑えたいので1:128にすればよさそうだ(20000/128=156.25)。オーバーフローで割り込みが発生するので、タイマーの初期値を256−156=100=64hにすればよい。
ほかにも設定するビットは色々とある。8ビットタイマーのプリスケーラはウォッチドックタイマと兼用であると資料に書かれているので、プリスケーラをタイマーで使う設定、プリスケーラの分周比の設定も必要だ。さらにタイマーのクロックに内部クロックを使う設定も必要になる。タイマーで割り込みを発生させるためには割り込み許可フラグ、タイマー割り込み許可フラグをセットする必要がある。この辺が初期化ルーチンに必要となる。なお、今回もメインルーチンは単なるループだ。
割り込み設定で使う基本のレジスタはINTCON($0Bor$8B)だ。割り込みを使うためには第7ビット(GIE)を1にする必要があり、さらに個別の割り込み許可フラグを1にする。今回はTMR0の割り込みを必要とするので第5ビット(T0IE)となる。
▼▼ | LIST P=PIC12F675 |
---|---|
▼▼ | INCLUDE "P12F675.INC" |
__CONFIG _INTRC_OSC_NOCLKOUT & _WDT_OFF & _MCLRE_OFF |
▼▼ COUNT | EQU | 22H | |
---|---|---|---|
▼▼ WBUF | EQU | 23H | |
SBUFEQU24H |
▼▼ | ORG | 0 | |
---|---|---|---|
▼▼ | GOTO | MAIN | |
▼▼ | ORG | 4 | |
GOTOINTMAIN |
ORG10 |
▼▼ | CLRWDT | |||
---|---|---|---|---|
▼▼ | CALL | 3FFh | ; 内蔵オシレーター調整 | |
▼▼ | MOVWF | OSCCAL | ||
▼▼ | BSF | STATUS,RP0 | ||
▼▼ | MOVLW | B'11010110' | ; TMR0 PRESCALE 128:1 | |
▼▼ | MOVWF | OPTION_REG | ||
▼▼ | CLRF | ANSEL | ||
▼▼ | BCF | STATUS,RP0 | ||
▼▼ | CLRF | INTCON | ||
▼▼ | BSF | INTCON,T0IE | ||
▼▼ | BSF | INTCON,GIE | ||
▼▼ | MOVLW | 64H | ||
MOVWFTMR0 |
GOTO LP |
▼▼ | MOVWF | WBUF | ; レジスタ類退避 | |
---|---|---|---|---|
▼▼ | SWAPF | STATUS,W | ||
▼▼ | BCF | STATUS,RP0 | ||
MOVWFSBUF |
▼▼ | MOVLW | 64H | ; タイマー再セット | ||
---|---|---|---|---|---|
MOVWFTMR0 |
▼▼ | BSF | GPIO,GPIO4 | |
---|---|---|---|
▼▼ | NOP | ||
▼▼ | MOVLW | 0F6H | |
MOVWFCOUNT |
▼▼ | NOP | |
---|---|---|
▼▼ | DECFSZ | COUNT,F |
▼▼ | GOTO | LOOP1 |
▼▼ | MOVLW | 1H |
▼▼ ; | MOVLW | 80H |
▼▼ ; | MOVLW | 0FFH |
MOVWFCOUNT |
▼▼ | NOP | |
---|---|---|
▼▼ | DECFSZ | COUNT,F |
▼▼ | GOTO | LOOP2 |
BCFGPIO,GPIO4 |
▼▼ | BCF | INTCON,T0IF | ; 割り込みフラグ復帰 | |
---|---|---|---|---|
BSFINTCON,GIE |
▼▼ | SWAPF | SBUF,W | ; レジスタ類復帰 | |
---|---|---|---|---|
▼▼ | MOVWF | STATUS | ||
▼▼ | SWAPF | WBUF,F | ||
▼▼ | SWAPF | WBUF,W | ||
RETFIE |
END |
Copyright © ITmedia, Inc. All Rights Reserved.