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


PICBASICコンパイラ

〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
まるでインタプリタ。でもコンパイラです。超カンタン超シンプルです。
〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜

[第14回]



●FOR NEXT文の実行時間

前回はPORTCに値を出力してすぐにPORTCの値を読むと正しい値が読み取れないという問題を回避するためにFOR NEXT文を間に入れるという方法について説明しました。
「わずかな時間」と説明しましたが実際にどのくらいの時間なのかについては何も書きませんでした。
実はそのように書いた私自身も実際に測ってみたわけではありませんから、多分短い時間だろうなあというぐらいの認識しかありません。
やっぱりこういうことは念のために確認しておくべきでありましょう。
ということで今回は簡単なテストプログラムを作って試してみることにしました。

その前に。
前回はI/Oポートでデータが誤って読み込まれる現象を「READ MODIFY WRITE問題」と書きましたが一般にPICで「READ MODIFY WRITE」という場合には少し意味合いが違っているところがありますから念のために補足しておきます。
PICで言う「READ MODIFY WRITE」はI/Oポートに対するビットセットやビットリセット命令など他のビットの状態を変化させないで特定のビットのみを変化させるために行なわれる動作のことを言います。
その場合には一旦I/Oポートから現在の出力値を読み込んでから特定のビットのみを変化させることでセット、リセットした後に再びその変更した値を出力します。
このときにもしもI/Oポートの外部に比較的大きな容量性の負荷がかかっていたり小さな値の抵抗でプルアップ、プルダウンされていて出力電圧が中間値になっていたりすると正しい値が読み込まれないために特定のビット以外の本来ならば変化しないはずの他のビットも変化してしまう可能性があります。
前回のようにI/Oポートに出力した直後にそのI/Oポートの値を読み込むときに誤読してしまうこともそれに近い現象ですがそれと「READ MODIFY WRITE」とは少し動作が異なっていることに後で気が付きましたので以上のように補足させていただきます。

さて。
それではFOR NEXTのテストプログラムについての説明にかかります。
下は[第10回]で作ったPORTC++のプログラムにFOR NEXT文を追加したプログラムです。

a=0から開始してaの値を+1ずつ加算します。
NEXTのところでaの値が9を越えたら(a=10になったら)FOR NEXTのループを抜け出します。
NEXTのところでa=1〜a=10までの繰り返しですからループは10回実行されます。
それとPORTC++とgoto 20の1回の実行時間の合計が1回のPORTCの出力処理のループに要する時間です。

上のプログラムを実行してPORTCのビット0の出力をCPLDロジアナで観測しました。
PORTCのビット0(RC0)はPROBE0に接続しました。

サンプリングクロックは5MHzです。
HとLで2μsの違いがありますがこれは5MHzでは測定限界です。
PORTCの1回の出力ループの実行時間は約8μsです。
マシン語ですから高速で実行されます。

もう少しFOR NEXTの時間を追及するために今度は30行のFOR文をa=0 to 1に書き換えました。

スクリーンエディタは便利です。
この画面のように必要な行をLISTコマンドで表示してカーソルを移動して書き換えるだけです。
上のほうに表示されているLISTの30行のところまでカーソルを移動していってそこで書き換えることもできます。
今回はFOR NEXTループは2回だけの実行です。

先ほどと同じようにCPLDロジアナでPORTCのビット0の出力を観測しました。

CPLDロジアナのサンプリングクロックは10MHzです。
FOR NEXT部分の2回の繰り返しを含むPORTC出力ループの1回の実行時間はL=3.2μs、H=3.3μsです。
サンプリングクロック10MHzで0,1μsは測定限界です。
さきほどはFOR NEXTは10回で8μsでした。
ちょっと計算が合いませんがこれはFOR文の設定部分の実行時間などが加算されるためです。
FOR NEXTの繰り返し回数が少ないほど全体に対するその部分の割合が大きくなります。
逆に繰り返し回数が多くなればその部分の割合は無視できるほどになります。

FOR NEXTの回数を20回にしてみました。


CPLDロジアナの観測結果です。

今回は14μsになりました。
先ほどのFOR NEXTが10回のときは8μsでした。
PORTC++やgoto 20、それとFOR文の設定部分の実行時間はどちらも同じだとするとその固定部分の時間をa、FOR NEXT1回の時間をxと置くと次の式が得られます。
a+20x=14
a+10x=8
この式を解くとx=0.6(μs)が得られます。
そしてaは2μsになります。
この値をさきほどのFOR NEXT2回の結果にあてはめると2+0.6×2=3.2μsですから計算通りの結果となっています。

今度はFOR NEXTの繰り返し回数をうんと増やしてみました。

a=0から99ですから100回の繰り返しです。
ここまでくると固定部分のaはほぼ無視できるようになります。

CPLDロジアナの観測結果です。

FOR NEXT100回の繰り返しに対して60μsですからaの時間は無視できることがわかります。

FOR NEXTの回数を200回にしました。

30行をfor a=0 to 199に書き換えました。

CPLDロジアナの観測結果です。

118μsです。
計算値よりも2μs足りませんが2μsの差はサンプリングクロック500KHzでは測定限界ですから120μsとしてよいでしょう。
120÷200=0.6ですから計算通りの結果です。

PICBASICコンパイラ[第14回]
2023.4.23upload

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