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


PIC−USBIO using BASIC

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

[第87回]



●PICUSBIO−03(36)Timer1(18)CAPTUREモード(9)謎の解明

前回はプリスケーラを1:2にしてテストしたところ異変がおきました。
計算によるTimer1のオーバーフロー回数は2*2=4なのですがプログラムを実行した結果はその倍の8回になってしまいました。
下位16ビットの値もその前のプリスケーラを1:4に設定したときの1/2になると予想されるところが1/2ではなくて同じ値になってしまいました。
続けて行なったプリスケーラ無しの設定でのテストでも全く同じ結果になりました。
計算によるTimer1のオーバーフロー回数は2回なのですがプログラムを実行した結果はその4倍の8回です。
下位16ビットの値もプリスケーラを1:4に設定したときと同じ値です。

この問題はオーバーフローの回数が鍵になっています。
それは原因がわかった今だからこそ言えることなのですが。
ついでに言ってしまいますがより正確に言いますと入力パルスの1周期の時間が鍵になっています。
入力パルスの1周期の時間に注目すると問題の原因が見えてくるようになります。
ここで重要なのは入力パルスの1周期の期間をTimer1の総カウント数から求めるのではなくてTimer0のカウント数を元にして計算しなければならないということです。
左側のPICUSBIO−03から出力されるパルスの1周期はTimer0が2回オーバーフローする時間です。
プリスケーラが1:8のときのTimer0の入力クロックは12/8(MHz)ですからTimer0が1カウントする時間は8/12(μsec)です。
Timer0が2回オーバーフローする時間は(8/12)*65536*2です。
プリスケーラの値が1:8以外のときの計算もしていきますから”8”を残したまま上の式を少し整理すると8*65536/6になります。
計算すると87381μsec(87.381msec)になります。

同じ計算をプリスケーラが1:4、1:2、1:1のときについてもやってみます。
プリスケーラが1:4のときは。
4*65536/6ですから1:8のときの1/2です。
43691μsec(43.691msec)です。

プリスケーラが1:2のときは。
2*65536/6ですから1:4のときの1/2です。
21845μsec(21.845msec)です。

プリスケーラなしのときは。
65536/6ですから1:2のときの1/2です。
10923μsec(10.923msec)です。

このように計算してみますと出力パルスの1周期の期間はプリスケーラの値に比例しています。
すると右側のプログラムで計算した入力パルスの1周期をカウントするTimer1の総カウント数も左側のTimer0のプリスケーラの値に比例するはずです。
ところが入力パルスの1周期が43.691msecまではそのようになっているのにそれよりも小さい値になると総カウント数が正しく表示されない現象が発生します。
不思議なことにその値は周期が43.691msecのときと同じになってしまうように見えます。

周期がある値よりも小さい値になるとCCPR1の値が正しい値ではなくて、まるで値が「飛んでいる」ように見えます。
ここまで考えて「そうだったか!」とやっと気が付きました。
もっと早く気がつくべきでした。
USB通信(HID)は遅いのでPICにアクセスするのに時間がかかります、と何回も書いてきましたのに。
原因はそこだったのです。

PICUSBIO用BASICインタプリタでPICにアクセスするにはmsec単位の時間がかかります。
何回もPICにアクセスする処理では数十msecの時間がかかります。
右側のプログラムは[第84回]にあります。
下に再掲します。

70行から130行までが繰り返し実行されます。
1回の繰り返しごとに1回のカウント数の表示が行なわれます。
その期間がどのくらいの時間なのかを確かめてみました。
上右のプログラムを下のように少し変更することでそれを確認することができます。

65行でPORTCのbit7の出力を毎回反転させるようにしました。
そのようにするために5行を追加しました。
PORTCのbit7を出力にしています。
今回のテストでは左側のPICUSBIO−03と右側のPICUSBIO−03とはこのテストのために作成した専用のフラットケーブルを使って接続しています。
RC4(パルス出力)とRC5(パルス入力)を結線するほかはGNDのみを結線しそのほかのラインはつないでいません。
ですから左側のRC7の出力と右側のRC7の出力がぶつかることはありません。

プログラムを実行して出力波形をオシロで観測しました。

上側(CH1)が入力波形で下側(CH2)がRC7の出力波形です。
これはプリスケーラが1:4のときの波形です。
CH1は上の方で計算した通り1周期が約40msecになっています。
それに対してCH2はCH1が1回立ち下がるごとに1回反転していますから正しくカウントできていると思われます。

下は水平時間軸を10msec/divにした波形です。

この波形を見るとCH2が反転しているのはCH1の下がりエッジの約10msec前ということがわかります。
余裕は10msecほどしかありません。

プリスケーラを1:2にしました。

CH1の周期は約20msecです。
それに対してCH2の反転出力はさきほどとほぼ同じ約40msecです。
やはり右側のプログラムの1回の処理には40msecほどの時間がかかってしまうようです。
CH2が1回反転する間にCH1は2回立ち下がっています。

水平時間軸を10msec/divにしました。

CH1の最初の立下りエッジでラッチしたカウントデータはBASICプログラムで表示されますが次のラッチデータはおそらく表示される前にさらにその次の立下りエッジでラッチされるデータのために失われてしまうであろうことが見て取れます。

プリスケーラなしの設定にしました。

CH1の波形が細かくなってちょっと見にくくなりました。
水平時間軸を10msec/divにしました。

CH1の周期は約10msecです。
それに対してCH2の反転出力はさきほどとほぼ同じ約40msecです。
CH2が1回反転する間にCH1は4回立ち下がっています。

これでやっと謎が解けました。
BASICプログラムがCAPTUREモードでラッチする1回のTimer1のカウントデータを表示するためには約40msecの時間が必要なのでそれよりも短い周期のパルスが入力されるとラッチしたデータを読み飛ばしてしまいます。
それが異常な値が表示されてしまう原因だったのでした。

PIC−USBIO using BASIC[第87回]
2022.10.30upload

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