2022.10.26
前へ
次へ
ホームページトップへ戻る


PIC−USBIO using BASIC

〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
USBインターフェースを内蔵したPICを使ってWindowsパソコンで外部回路を制御するための各種I/O基板の製作記事です。
〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜

[第84回]



●PICUSBIO−03(33)Timer1(15)CAPTUREモード(6)T1H3、T1H2

前回までは入力パルスの1周期間をカウントするTimer1のカウント総数は計算で求めていただけで実際にそれを確認したわけではありませんでした。
今までのテストでは入力パルスの周期はわかっていたので計算で求めることができたのですがそれはあくまでテストでの話です。
実際にはパルスの周期がわからないのでそれをTimer1でカウントして求めるというのがCAPTUREモードのそもそもの目的のはずです。
入力パルスの周期はCAPTUREモードのプログラムで表示される連続する2回のCCPR1レジスタの値の差とTimer1のオーバーフローの回数から求めることができます。
するとCAPUTUREモードの機能を生かすためにはどうしてもTimer1のオーバーフロー回数を求めなければならないということになります。
どうすればTimer1のオーバーフローの回数を求めることができるでしょうか。
考えてみたのですがやっぱりTimer1のオーバフロー割り込みを使ってその回数をカウントするしかほかに方法はないようです。
Timer1のオーバーフロー割り込みは既に使っています。
[第74回]でTimer1のオーバーフロー割り込みが発生するたびにPORTCのbit3(RC3)の出力を反転させる割り込みプログラムをPIC18F13K50に組み込みました。
その割り込みプログラムに割り込みのたびにレジスタの値を+1するプログラムを追加すれば、そのレジスタの値をBASICプログラムで読むことでTimer1のオーバフロー回数を知ることができるはずです。
それにはTimer1の割り込みプログラムを追加変更するとともに追加した割り込み回数をカウントするレジスタをPICUSBIO用BASICインタプリタで読むことができるようにするためのプログラム変更作業も必要です。
そのように作業を行なったあと、今までと同じ要領でCAPTUREモードのテストを行いました。

右側のコマンドプロンプトのBASICプログラムは今までのCAPTUREテストプログラムにTimer1の割り込み回数をカウントするレジスタの値も表示するように追加変更したプログラムです。
Timer1の割り込みについては[第74回]で説明をしています。
Timer1の割り込みを有効にするにはINTCONのbit7とbit6を1にする(10行)とともにPIE1のbit0を1にします。
しかし50行ではPIE1に5を設定しています。
bit0だけではなくてbit2も1にしています。
実はTimer1の割り込みを使うだけでは不十分でCCP1の割り込みも必要であることがわかりました。
PIE1のbit2を1にすることでCCP1の割り込みが有効になります([第74回]参照)。
CCPR1レジスタは入力パルスの下りエッジでTimer1レジスタの値をラッチしますがTimer1のオーバーフローはそれとは無関係に発生します。
残念ながらBASICインタプリタは速度が遅いためにCCPR1の値を読み込んだときにTimer1のオーバーフロー割り込みをカウントするレジスタの値が変わってしまっている可能性があります。
CCPR1はラッチされているので今まではあえて割り込みを使わなくても入力パルスの下りエッジの時の値を読むことができました。
しかしそれと同時にTimer1のオーバーフロー割り込みをカウントするレジスタの値も正しく読もうとするとそのレジスタの値もラッチしておかなければならないということがプログラムを変更してテストをしていく過程でわかってきました。
いささかややこしい話ですがTimer1のオーバーフロー割り込みだけではだめでそれに加えてCCP1の割り込みも使わなければならないということです。
そのようにCCP1の割り込みを使うことにしたため今までのプログラムはさらに変更が必要になりました。
70行と90行のCCP1IFレジスタです。
CCP1IFはPIR1のbit2にあります。
CCP1がTimer1レジスタをラッチするタイミングでCCP1IFがセットされます。
今までのテストプログラムではそれ(PIR1のbit2)がセットされるかどうかをチェックすることで入力パルスのエッジのタイミングを知るようにしていました。
そしてCCPR1の値を読んだあとでPIR1のbit2をクリアしていました。
しかしCCP1の割り込みを使う場合にはPIR1のbit2のクリアは割り込みプログラムで行なわれます。
今までのようにPIR1のbit2を読んでもそのときにはクリアされてしまっている可能性が高くなります。
これもややこしい話なのですがその問題を回避するためにPIR1のbit2とは別に用意したレジスタが70行と90行のCCP1IFです。
CCP1IFレジスタはCCP1割り込みのときにセットされますが割り込みプログラムではクリアされません。
PIR1のbit2と同じ名前ですがそれとは全く別に今回のプログラム変更のために用意したレジスタです。
ややこしいですね。
とにかく割り込みプログラムはややこしくてむつかしいのです。
110行のT1H3とT1H2がTimer1のオーバーフロー回数をカウントするレジスタです。
T1H3が上位8ビット、T1H2が下位8ビットです。
ともにCCP1割り込みでラッチされます。
CCPR1割り込みでTimer1カウンタのTMR1H(上位8ビット)がCCPR1HにラッチされTMR1L(下位8ビット)がCCPR1Lにラッチされますから、T1H3、T1H2、CCPR1H、CCPR1Lをその順に並べると32ビットの連続したカウンタになります。
そこで120行のprint文は今までの表示とは順序を変更して上記の順に表示するようにしました。

説明が長くなってしまいましたので、プログラムの実行については次回にいたします。

PIC−USBIO using BASIC[第84回]
2022.10.26upload

前へ
次へ
ホームページトップへ戻る