PIC−USBIO using BASIC
〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
USBインターフェースを内蔵したPICを使ってWindowsパソコンで外部回路を制御するための各種I/O基板の製作記事です。
〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
[第65回]
●PICUSBIO−03(14)Timer0(2)TMR0HをPORTCから出力
Timer0はシンプルなタイマ/カウンタです。
Timer0レジスタの値をREADすることで現在のカウント値を読むかオーバフロー割り込みによってオーバーフローを知る以外の機能はありません。
それだけではTimer0の動作テストにはなりませんからここは工夫が必要です。
そこでTimer0の値(上位バイトの値)を読んでそれをPORTCから出力するように考えてみました。
そのPORTCの値をオシロで観測してみます。
下がプログラムリストです。
たったこれだけです。
めっちゃ簡単です。
10行でPORTCの向きを出力に設定しています。
20行でTimer0を設定しています。
設定については前回を参照してください。
bit7=1でカウントスタートです。
bit6=0で16bitカウンタに指定しています。
bit5=0で入力クロックをシステムクロック/4(12MHz)に指定しています。
bit3=0でプリスケーラを使います。
bit2〜0=111でプリスケーラの分周比を1:256に指定しています。
このときクロック入力は12MHz/256=46.875KHzです。
今回はTimer0の上位バイトの値を読み込んでPORTCから出力します。
上位バイト(TMR0H)を読むためには先に下位バイト(TMR0L)を読む必要があります(前回参照)。
それが30行〜50行です。
60行で30行に戻って繰り返します。
前回も少し書きましたが通常PICのプログラムで避けて通れないのがConfigの設定です。
PICUSBIO用BASICインタプリタはシステムが設定しますからユーザーが考える必要はありません。
Cでのプログラムは色々な前準備的な設定が必要です。
さらにいえばPIC用のCコンパイラはPIC専用ですから汎用のCにはない専用の設定が必要(なはず)です。
BASICインタプリタにはそんなものは全く不要です。
いきなりプログラムを書いていきなり実行できてしまいます。
さらに、そもそもですが。
Cコンパイラなどを駆使してPICのためのソースプログラムを書いてそしてそれをコンパイルして無事にオブジェクトプログラムができたとしまして。
PICにそのプログラムを焼くためにはPIC WRITERが必要でありましょう。
PICUSBIO用BASICインタプリタにはそれも不要なのです。
プログラムを書いたら、あるいはプログラムをLOADしたら、いきなりRUNできてしまいます。
もう、あきれるほど簡単です。
下はPORTCのビット7(RC7)とビット6(RC6)の出力パルスをオシロで観測した画像です。
上側(CH1)がRC7で下側(CH2)がRC6です。
16ビットカウンタの最上位ビットがRC7から出力されています。
プリスケーラを経由したカウンタの入力周波数は上で計算しました。
46.875KHzです。
カウンタの最上位ビットの値が出力されているRC7の周波数は46875/65536≒715Hz(周期は約1400msec)です。
その下位のRC6の出力周波数は約1430Hz(周期は約700msecです)。
計算通りの出力が得られています。
プリスケーラの値を1:128にして再実行しました。
20行のpicout T0CON,$87をpicout T0CON,$86に書き換えるだけです。
LIST 20で20行を表示させてスクリーンエディタで$87を$86に書き換えました。
そしてただちにRUNで実行できます。
もう一度書きますが。
こんなに簡単なPICプログラムなんてほかにありますでしょうか?
上のプログラムの実行結果です。
プリスケーラを1:128にしましたからカウンタの入力周波数は12MHz/128=93.75KHzになります。
カウンタの最上位ビットの値が出力されているRC7の周波数は93750/65536≒1430Hz(周期は約700msec)です。
その下位のRC6の周波数は約2860Hz(周期は約350msecです)。
さきほどのオシロ画像と同じように見えますがさきほどの画像は水平時間軸が200msで今回は100msになっています。
プリスケーラの値を1:64にして再実行しました。
20行の$86を$85に書き換えてRUNしました。
上のプログラムの実行結果です。
プリスケーラを1:64にしましたからカウンタの入力周波数は12MHz/64=187.5KHzになります。
カウンタの最上位ビットの値が出力されているRC7の周波数は187500/65536≒2860Hz(周期は約350msec)です。
その下位のRC6の周波数は約5720Hz(周期は約175msecです)。
さきほどのオシロ画像と同じように見えますがさきほどの画像は水平時間軸が100msで今回は50msになっています。
プリスケーラの値を1:32にして再実行しました。
20行の$85を$84に書き換えてRUNしました。
上のプログラムの実行結果です。
プリスケーラを1:32にしましたからカウンタの入力周波数は12MHz/32=375KHzになります。
カウンタの最上位ビットの値が出力されているRC7の周波数は375000/65536≒5722Hz(周期は約175msec)です。
その下位のRC6の周波数は約11444Hz(周期は約87msecです)。
オシロの水平時間軸は20msです。
プリスケーラの値を1:16にして再実行しました。
20行の$84を$83に書き換えてRUNしました。
上のプログラムの実行結果です。
プリスケーラを1:16にしましたからカウンタの入力周波数は12MHz/16=750KHzになります。
カウンタの最上位ビットの値が出力されているRC7の周波数は750000/65536≒11444Hz(周期は約87msec)です。
その下位のRC6の周波数は約22888Hz(周期は約44msecです)。
オシロの水平時間軸は20msです。
波形を見るとCH1は左側の1波は92〜96msぐらいで次の1波は80msちょうどぐらいに見えます。
2波を合わせると176msぐらいなので大体計算が合います。
CH2はCH1には同期していますがデューティ比が50%からかなりずれています。
これはTimer0の誤差ではありません。
理由があります。
その原因はUSB通信です。
PICUSBIO用のBASICインタプリタのUSB通信はHID方式です。
HID方式は特別のドライバをインストールする必要がなく簡便なのですが欠点は通信速度が遅いことです。
それを確認するために下のプログラムを実行してみました。
PORTCから00とFFを交互に出力するだけのプログラムです。
上のプログラムの実行結果です。
PORTCに1回アクセスするのに2msかかっています。
これがPICUSBIO用BASICインタプリタのちょっと弱いところです。
Timer0のプログラムではTMR0Lにアクセスして次にTMR0Hにアクセスして次にPORTCにアクセスしてそれを繰り返します。
つまりPORTCからデータを1回出力するのに6msかかる計算です。
その周期が長いときは目立ちませんがさすがに周期が88ms、44msということになるとその影響は無視できなくなります。
今回のTimer0のテストプログラムではプリスケーラを使ってさらに16ビットモードでその上位バイトのデータを読んでそれをPORTCから出力するようにしたのはその理由からです。
遅い!遅過ぎる!
とお考えかもしれませんが。
PICUSBIO用BASICをPICの入門用ツールとして考えれば遅いという欠点を埋めてもなお余りある利点が大いにあると思うのですがいかがでしょうか?
PICUSBIO用BASICインタプリタのpicout、picinを使ってPICのレジスタに直接アクセスするという試みはまだ始まったばかりです。
回が進むにつれて、きっと「いいぞ、いいじゃないの」と思っていただけると確信しております。
PIC−USBIO using BASIC[第65回]
2022.9.29upload
前へ
次へ
ホームページトップへ戻る