こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

PICで内部タイマーを使わずカウントダウンする方法

こんにちは。
今回、PICのプログラムをアセンブラで組むことになりました。

その中で「100ミリ秒間、あるポートからの入力を監視する」という部分があり、
これを内部タイマーなどは使わずに実装するとします。

自分なりには、
PICのクロック数とループ内のサイクル数で
何回ループを回せばよいのかを予め計算しておいて
その回数だけループを回せばよいのかな?
と考えました。。。

しかしループ内のサイクルがせいぜい数μSですので、
100mSecとなると10万回単位でループを回さなければなりません。

しかしPICでは変数が8Bitしか無いので255までしかカウントできないと思うのですが、
こういう大きい数字のカウントをしたい場合、どうしたら良いのでしょうか?
宜しくお願いします。

投稿日時 - 2013-12-22 03:02:00

QNo.8396056

すぐに回答ほしいです

質問者が選んだベストアンサー

他の回答者の回答を見てると、最近はアセンブラ等でソフトを組む人は居ないんだなぁ。と思ってしまいますね。

>「100ミリ秒間、あるポートからの入力を監視する」

とどまっているんじゃなくて、監視し続けなければならないのでしょう。
重い処理なんてはさんだら、性能が落ちちゃいますし、見落としますからね。


ポートの入力は、割り込み信号は上がるのでしょうか?それとも、ポーリングを掛けて見続けていなければならないのでしょうか?
これで作り方は変わります。


通常、こういうプログラムの作り方は、一定の処理をダイナミックループで回していて、その中で、各処理を行っていくのが普通です。

なので、ダイナミックループの中にある、サブルーチンの平均所要時間を割り出してやると、ダイナミックループ1回にかかる時間が判ります。
このダイナミックループの中に、カウンタールーチンを作っておいて、何回回ったかを記録してその回数で、時間の経過を測定します。

指定時間内だけポートをチェックするのであれば、そのダイナミックループの中にポートチェックを入れておいて、カウンタールーチンで積算されている内容で、ポートチェックのルーチンに入るのかはいらないのかをすればよいだけです。

割り込み処理があるのなら、カウンタールーチンを、ダイナミックループに入れる必要は無く、割り込み処理の方に入れてやればよいだけです。
当然カウンタールーチンで、割り込みを開放、停止すればそもそもチェックに行く必要もなくなるわけです。

8ビットしかないからと言うのは、他の人も書かれて居る様に、単純に増やせばよいだけの話です。
カウンタ用の1バイトがいっぱいになってたら上位桁用の1バイトにインクリメントしてあげれば、1ビットのカウンタになるでしょう?
そんなに難しい話ではないと思います。

nopは、コンパイラによっては、削除されてしまう物もあります。
その辺は仕様書を読まないと判りませんけどね。
nopコードとして入れてくれる物もあるのですけどね。


タイマーなんて持っていないCPUを使う時はこんな方法は良く使って居ましたね。
途中に思い処理が分岐で入ると、そこを通ったか通らなかったかで、タイマーのカウンタの上げ方も変えなければならなかったですからね。

カウンタが足りないだけなら、上の様に増やせばよいだけの話です。

投稿日時 - 2013-12-26 15:53:25

お礼

皆さん有難うございました。
皆様の仰る通り、気づいてみたら特に難しいものではなかったです。

タイマー的な動作をループのネストで作ると
ステップ数を自分で計算しなければいけないので
面倒そうだし精度的にもどうかなと思ったのですが、
目的のものがそれほど精度を要求するものではなかったので、
あとはループの一番内側でポートの状況を毎回見ておく
という感じでとりあえず要求を満たすことができました。

ありがとうございました。

投稿日時 - 2014-02-20 02:37:43

このQ&Aは役に立ちましたか?

0人が「このQ&Aが役に立った」と投票しています

回答(6)

ANo.6

(1)
(必要なら割り込み停止)
ループ {
 ループ {
  ループ {
   監視処理
  }
 }
}
(必要なら割り込み許可)

(2)
100ms毎に割り込み初期化
割り込みタイミング合わせ
無限ループ {
 監視処理
 割り込みがかかっていたら抜ける
}

投稿日時 - 2014-01-11 12:36:27

ANo.4

ネストで回すのと同じ考え方ですが、アセンブラなので違う書き方をすると、
カウンタのカウンタを作ればいいでしょう。
カウンタが0から255に来たら、一回まわったとして別のカウンタをプラス1して
255になったカウンタは0に戻すわけです。
結局、8bitxnのカウンタを自分で作るわけですね。

投稿日時 - 2013-12-22 09:01:33

ANo.3

あ、ネストの字下げtabが消えて見にくくなってしまった・・・

投稿日時 - 2013-12-22 07:04:43

ANo.2

ループをネストすれば良いのでは?
例えば下記のようにすると255×255回のループになりますね。
足りなければ更に多重化すれば良いです。
下の場合、iとjはunsignedにすることをお忘れなく・・・
for ( i=0 ; i < 0xff ; ++i ) {
for ( j=0 ; j < 0xff ; ++j ) {

投稿日時 - 2013-12-22 07:01:12

ANo.1

数ミリ秒かかる一連の命令を必要数回せばいい。

ってか、割り込みが発生したらタイミングがずれるのでそのやり方はお勧めできないのが正直なところなんだけどさ。

投稿日時 - 2013-12-22 03:38:47

補足

ご返信ありがとうございます。
要するに時間稼ぎのための重い処理を挟む、ってことでしょうか?
例えばNOPを沢山書くとか・・・ウェイトを挟むような?

ですがそうするとその時間稼ぎしている間に
ポートのチェックが疎かになってしまうと思うのですが、
どうでしょうか?

投稿日時 - 2013-12-22 03:57:19

あなたにオススメの質問