
今更ながらPIC16F84Aを使ってサーボを動かすプログラムの勉強を始めました。
サーボを動かすためにマイクロ秒単位のタイマーを作らなければならないのでそのためにサンプル的に以下の様なプログラムを作ってみました。
アセンブリ言語とPA.EXEという古い環境ですが・・・
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
include 16f84.h
.osc hs
.wdt off
.protect off
org 0ch
tm1 ds 1
tm2 ds 1
org 0
goto start
org 4
goto start
start
clr ra
clr rb
mov !ra,#00000b
mov !rb,#00000000b
ntl
mov rb,#00000001b ;
call wait10
mov rb,#00000000b
call wait10
goto ntl
wait10
movlw 50 ;①
movwf tm1
wait10_1
movlw 128 ;②
movwf tm2
wait10_2
nop
decfsz tm2,1
goto wait10_2
decfsz tm1,1
goto wait10_1
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
プログラムをコピペしたら変になったので一応画像も添付しております。
使用するクロックは10Mのセラロックです。
①、②の値を変えればラベルwait10_2内のnop命令の繰り返し回数が変化し、ラベルntlでのポートRB0からの出力時間を変化させられると思います。
この時間を10マイクロ秒にするには①、②の値(もしくは①×②の値?)をどのようにすれば良いのでしょうか?
また、現在は仮に①=50 ②=128としていますが、この値のままでラベルwait10の行からwait10_2までを実行し終わった時にかかる時間の計算はどのようにすれば良いのでしょうか?
10マイクロ秒のタイマーの作り方が分かれば後はそれを応用して簡単なサーボコントローラーに応用していきたいと思います。
よろしくお願い致します。

A 回答 (3件)
- 最新から表示
- 回答順に表示
No.3
- 回答日時:
ひとつ注意点として、
恐らく10マイクロ秒固定の時間待ち関数が目的ではなく、10マイクロ秒単位で任意の時間を待つ関数を作るつもりだと思いますが、
これを10マイクロ秒待ちをループで繰り返すように作ると、ループ処理の部分に掛かる時間の分だけずれます。
例えばループ処理に1.2マイクロ秒掛かるなら8.8マイクロ秒待ちの処理を作る必要がありますのでご注意ください。
処理にかかる時間の計算ですが、
PICは本来、非常に処理時間を計算しやすいマイコンです。
すべての命令が4クロックの倍数で動くので、4クロックを「1サイクル」と称します。
ほとんどの命令は、実行に1サイクル(4クロック)掛かります。
GOTO・RETURN・「addwf PCL」などの分岐命令は2サイクルです。
スキップ系命令(BTFSS・INCFSZなど)は考え方が2通りあり、
「条件が満たされた場合は次の命令をスキップして2サイクル、条件が満たされない場合は次の命令をスキップせず1サイクル」と見るか、
「常に1サイクルで実行し、条件が満たされた場合は次の命令の代わりにNOPを実行する」と見るかで、表現に差があるので資料を見る時はご注意ください。
しかし問題はPA.EXEの独自表記で、アセンブラ命令でない「mov !rb,#00000000b」などものはどれだけ時間が掛かるか分かりません。
PA.EXEの説明書を見るか、ビルドした結果を見るなどしてください。
また、PA.EXEをやめてMPLABを使えばシミュレータで実行サイクル数を確かめられます。PA.EXEの独自書式は使えなくなりますが、純粋なアセンブラ部分は変わりませんのでさほど移行に障害はないでしょう。
No.2
- 回答日時:
> この時間を10マイクロ秒にするには①、②の値(もしくは①×②の値?)をどのようにすれば良いのでしょうか?
このプログラムでは遅延部分が二重ループになっているのであまり短い周期のタイマーは作れません。
2つのパラメーター(現在128と50)を共に1にした場合、ポート出力が1(High)になる時間がたぶん16クロック、0(Low)の時間がたぶん18クロックになるはず。クロック発振が10MHzならば命令1個の実行時間は0.4μ秒ですから1周期は約13.6μ秒になるはずです。これが最短周期です。このままではこれより短い周期にはできません。
もっと短い周期にするにはループを一重にすればよいのです。例えば
wait10 movlw ▼
movwf tm2
wait10_2 decfsz tm2,1
goto wait10_2
ret
これで最短処理時間は6サイクルのはず。親ルーチンのCALL等を含めると9サイクル前後のはずですからクロック発振が10MHzならば最短周期が7~8μ秒のパルスが出せるはずです。
▼の値は必要なパルス幅に応じて変えてください。値を1増すと出力パルスの周期は2.4μ秒長くなります。
> 現在は仮に①=50 ②=128としていますが、この値のままでラベルwait10の行からwait10_2までを実行し終わった時にかかる時間の計算はどのようにすれば良いのでしょうか?
主ループはNOPからの3命令。命令の実行時間はNOPとDECFSZは1サイクル、GOTOは2サイクルなので合計4サイクル。
これを 128×50 回繰り返すので25600サイクル要します。
クロック発振が10MHzならば1サイクルが0.4μ秒ですからこのサブルーチンでの遅延時間は10.24m秒になります。
この計算式は 0.4μ秒 × 4サイクル × 128 × 50 = 10.24m秒
したがって出力周波数は 1 ÷ ( 10.24m秒 × 2 ) = 48.8Hz
以上は概算です。この計算にはMOVLWやRETを含んでいないので実際にはもう少し低い周波数になります。
PIC16F84Aが持つタイマーはオーバーフロー型のタイマーです。割込が掛けられるだけでハードウェアでは出力されていないので短周期のパルスは作れません。
PICの一部の品種ではタイマーに初期設定するだけでソフトの負担なしで高速パルスを出すことができます。例えばPIC16F178xシリーズなど。200KHzぐらいまでは出したことがありますが最高で8MHzまで出るはず。タイマーへの設定値を N(8bit) として、 発振周波数 ÷ N の周波数が取り出せます。Duty比も変えられPWM機能もあります。
No.1
- 回答日時:
PICで正確な単位のタイマーを作るにはタイマー0を使った割り込み以外無いと思いますがクロックがセラロックというのは矛盾があると思います。
この精度は±0.5%です。最大1%の狂いがあるので例えば1秒パルスを作ったら1%=10msずれが発生するとなり、100カウントすると1秒ずれることになります。なのでセラロックではマイクロ秒単位のタイマーは作れません。PA.EXEの資料が見つからないのでタイマー0を使った割り込みが使えるかどうか不明です。この質問のデバッグ方法は30年以上前のZ80全盛時代の自作ホビーストがやっていた方法で古過ぎます。PICはICSPが出来るのでPICKIT3を買ってきてやった方が早いです。デバッグもMPLABという無償のプログラマで出来るのでプログラムを見ながらステップ動作やレジストリ内のモニタは自由に出来ます。
PA.EXEを調べていたとき偶然に貴方の過去の質問を見ました。日付は2007年でした。そんなに苦労しているならC言語を勧めます。こちらのほうが記述が簡単でわかりやすいと思います。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Excel(エクセル) EXCELのグラフを画像(JPG形式)で保存、通常実行がうまく行かない。ステップインはうまく行く 3 2022/08/30 12:06
- C言語・C++・C# Cのオブジェクトファイルの逆アセンブル 5 2023/05/13 01:51
- 仕事術・業務効率化 効率的な勉強方法(分野問わず)を教えてください 1 2023/08/16 01:33
- その他(プログラミング・Web制作) プログラムの勉強のおすすめは 7 2022/12/09 20:09
- C言語・C++・C# このプログラミング誰か教えてくれませんか 1 2022/06/02 15:27
- C言語・C++・C# win10で、正確な待ち時間の作り方 6 2023/02/14 18:28
- C言語・C++・C# C言語 3 2022/10/04 15:07
- その他(ソフトウェア) F-BASICで計算中の実行が中途で勝手に止まり、大変困っています。 2 2023/03/02 16:15
- 英語 決意表明の"be going to"と意志の"will"の違いについて 6 2023/04/11 23:04
- 英語 be sorry for doingとbe sorry to have doneの意味の違いについて 2 2023/06/09 13:57
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
関数と命令の違いについて
-
パイプライン処理の処理能力に...
-
VB.net2010 割り込みの共通化
-
64ビット化による処理速度低下...
-
組み込みCプログラムで実数型
-
EXCELでの16進数取り出し、上...
-
EXCEL16進⇒浮動小数変換したい
-
携帯電話の略語であるMBって英...
-
2ビット、3ビット、4ビットのグ...
-
文字の容量(サイズ)についての...
-
エクセルVBAで xlOn xlOff の切替
-
有効数字計算 確定した値を含む
-
【有効数字について】 授業で、...
-
エクセルでビット1をカウント J...
-
かけ算(わり算)と足し算(引き算...
-
実行計画の「COST」と「BYTE」...
-
1テラバイトに、CDが何枚はいる...
-
なぜ1と0か?
-
oracle11gで、PL/SQLにてAとい...
-
VBAで時間の型と計算方法教えて...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
プログラム言語FortranとCの違...
-
組み込みCプログラムで実数型
-
MIPS と クロック周波数の換算方法
-
COM1(RS232C)とUSB仮想COMポー...
-
ステート数とは
-
PICマイコンのプログラムについ...
-
arduino
-
64ビット化による処理速度低下...
-
CPU、Z80からステート数から...
-
任天堂64の64 CPUの仕...
-
VBSとVBA
-
アセンブリ言語で。
-
+=と÷=の処理速度の謎を教え...
-
VBAでのコントロール操作
-
命令網羅率の計算問題です
-
CPUのHTについて教えてください。
-
MFCのエディットボックス上書き...
-
応用情報技術者試験問題の解き...
-
マイコンのビット数とクロック数
-
なぜ、i++なのか?(ものすごく...
おすすめ情報