PICで一定時間のスリープ(ウェイト)を行うnanoblog(ナノブログ)HomeWordPressJavaScriptC#読書メモ電子回路RSSPICで一定時間のスリープ(ウェイト)を行う2012年6月30日アセンブラではスリープ処理も,ひと苦労プログラムの中で一定時間処理を止めたい場合、C言語だとsleep()関数を使用することで秒単位のスリープ処理を行えます。PICでアセンブラを使って処理を行う場合はどうかというと、残念ながら一定時間処理を待つという命令は有りません。アセンブリのニーモニック一覧を見るとSLEEPというのがあるので、一見するとこれでいけそうな気もしますが、残念ながらPICのSLEEPはMPU自体をスリープモードにする(Windowsでいうサスペンド状態)命令なのでこれは使えません。このような場合、PICではループを空回しする事でビジーウェイトを作り、所定の時間だけ経過させるという方法を取ります。何回ループを空回りさせるべき?ループ空回りで時間をつぶすのは良いとして、ここで問題になってくるのは、ループを何回まわす必要があるかが分からないという事です。これに関しては、PICのクロック周波数から1命令あたりの消費時間を求めて、計算を行うという手間が必要になってきます。クロック周波数と周期は逆数の関係になるので、例えばPICを20Mhzで駆動させている場合1クロックサイクルは”20M分の1秒”になります。1Mは100万なので2000万分の1秒ということになります。PIC16F84Aのチップを使っている場合、1命令の実行に4クロックサイクル(分岐命令を除く)必要となります。1命令の実行に必要な時間は500万分の1秒です。これは計算すると200ナノ秒(0.2マイクロ秒)に相当します。先ほど”1命令の実行に4クロックサイクル必要”と書きましたが、自分が使用しているチップが1命令あたり何サイクル必要かは、製造元のMicrochipが公開しているデータシートに載っています。データシートから引用した上の図を見ると、OSCから入力されたクロック4つで、PC(プログラムカウンタ)が1回分処理される事が分かります。データシート最初に記載されている、機能一覧ページを見ると以下のような記述があり、ここからも上記の計算が合っていることが分かります。cycleというわけで、仮に1マイクロ秒の待ちを発生させたい場合は、5命令分の待ちが必要ですし、1ミリ秒待ちたいなら5000個の命令を実行されれば良いことが分かります。GOTO命令などの分岐命令は、2サイクル分の時間が必要な事に注意が必要です。アセンブラでウェイト処理を作る上記の計算で基礎資料がそろったので、実際にウェイト処理を作ります。WAIT_USECレジスタで、指定された時間(マイクロ秒)だけ待つ。WAIT_USECレジスタで、指定された時間(マイクロ秒)だけ待つ。RETURN上記の処理を見てみると、WAIT_TIMEラベルで示される処理でループを行っています。ループはNOPが2,DECFSZが1つ,そしてgotoが1つあり、gotoは命令の実行に2サイクル必要なので、合計2+1+2=5命令分の時間を消費し、丁度1マイクロ秒の待ちになります。それをWAIT_USECレジスタに指定された回数分ループさせています。この処理の呼び出し元は、以下のような記述になります。CALLWAIT_TIMEWAIT_USECにスリープさせたい時間を予めセットしてからWAIT_TIMEサブルーチンをコールする事で、任意の時間処理をスリープさせる事が出来る様になりました。※ループ処理について知りたい場合は、こちらの記事も参考にしてくださいPICアセンブラにおける分岐/ループ処理の組み立て方この方法の欠点は?上記の方法で、指定した時間だけ処理を待たせる事が可能となりましたが、残念ながらこの方法も万能では有りません。何らかの処理を行いながら、10秒ごとにブザーを鳴らしたいという処理があった場合、上記の方法だと10秒間、空ループをひたすら実行し続ける事になるので、他の処理が行えません。10秒の間に”何らかの処理”のほうを作業させてしまうと、この処理に何クロックサイクル使用するかを確定できない為、こんどは10毎に処理を行うということが出来なくなってしまいます。上記のような場合は、割り込み機能というものを使って対応する事になるのですが、これについてはまた後日書くことにします。コメントをキャンセルメールアドレスが公開されることはありません。29お勧め書籍webアプリのセキュリティ対策の為に。