====== 単純なウェイト処理 ======
===== ウェイト値の求め方 =====
まず動作クロック(1秒間に処理できるステート数)を調べます。\\
今回は秋月の3052なので25MHz=25000000Hz。\\
1ms=0.001sのウェイトなので、25000000/1000=25000。\\
25000ステートの待ち時間を作れば良い事になります。\\
\\
で、プログラムのステート時間を調べるのですが、ここに大きな問題があります。\\
プログラムや、データの置いてあるメモリによって実行速度が違います([[実行ステート数表]])。
^ 命令 ^ ニーモニック ^命\\ 令\\ フ\\ ェ\\ ッ\\ チ^分\\ 岐\\ ア\\ ド\\ レ\\ ス\\ リ\\ ー\\ ド^ス\\ タ\\ ッ\\ ク\\ 操\\ 作^バ\\ イ\\ ト\\ デ\\ ー\\ タ\\ ア\\ ク\\ セ\\ ス^ワ\\ ー\\ ド\\ デ\\ ー\\ タ\\ ア\\ ク\\ セ\\ ス^内\\ 部\\ 動\\ 作^プ\\ ロ\\ グ\\ ラ\\ ム\\ 内\\ 部\\ \\ デ\\ ー\\ タ\\ 内\\ 部^プ\\ ロ\\ グ\\ ラ\\ ム\\ 内\\ 部\\ \\ デ\\ ー\\ タ\\ 外\\ 部^プ\\ ロ\\ グ\\ ラ\\ ム\\ 内\\ 部\\ \\ I\\ /\\ O\\ \\ ^プ\\ ロ\\ グ\\ ラ\\ ム\\ 外\\ 部\\ \\ デ\\ ー\\ タ\\ 内\\ 部^プ\\ ロ\\ グ\\ ラ\\ ム\\ 外\\ 部\\ \\ デ\\ ー\\ タ\\ 外\\ 部^プ\\ ロ\\ グ\\ ラ\\ ム\\ 外\\ 部\\ \\ I\\ /\\ O\\ \\ ^
| MOV |MOV.B #xx:8,Rd| 1 | | | | | | 2 | 2 | 2 | 6 | 6 | 6 |
開発環境は大きく別けて3つ。\\
-プログラムやデータが小さいものを内部RAMのみでデバッグ。(ROMと同じ実行速度)\\ 表で言うと、「プログラム内部 データ内部」と「プログラム内部 I/O」になります。\\
-プログラムやデータが大きいので外部RAMのみでデバッグ。\\ 表で言うと、「プログラム外部 データ外部」と「プログラム外部 I/O」になります。
-プログラムやデータが大きいので外部RAM、速度が必要なものは内部RAMでデバッグ。\\ 表で言うと、「プログラム外部 データ内部」と「プログラム外部 データ外部」と\\ 「プログラム外部 I/O」になります。
1と2の実行速度は2~3倍くらい違います。外部RAMのみ処理落ちしてもROM化すると\\
動く可能性があります。
===== 1msウェイト =====
LEDの点滅をさせたりするために簡単なウェイト処理を書いてみます。\\
まず関数の説明を書きます。\\
;******************************************************************************
; 1ms ウェイト(25MH で 25000-10)
;
; _Wiat1ms
; 2004/11/06 : 初期バージョン完成
;
; [書式] void Wait1ms(Uint16 wait) ;
;
; [IN] wait = ウェイト値(ms)
;
; [OUT] なし
;
; [DED] ER0
;******************************************************************************
C言語からも、アセンブラからも呼べるように宣言。
public _Wait1ms
public WAIT_1ms
C言語なら引数をE0に取得(_Wait1ms)。\\
アセンブラなら既にE0に値が入って呼ばれるので処理なし(WAIT_1ms)。
_Wait1ms: MOV.W @(4,ER7),E0 ; 6:14 E0 = wait
WAIT_1ms:
1ms分ループで待つ。ウェイト値(3120と1038)は動作モードによって変更します。\\
内部 RAM のみなら、以下のようになります。\\
\\
25000 = 呼び出し時間-セットアップ時間 - ループ時間 x n - リターン時間\\
n = (25000 - 呼び出し時間 - セットアップ時間 - リターン時間) / ループ時間\\
n = (25000 - 10 - 6 - 4 - 4 - 4 - 6 - 10) / (4 + 4) = 3119.5 ≒ 3120\\
MOV.W #3120,R0 ; 4:12 ROM か 内蔵 RAM
; MOV.W #1038,R0 ; 4:12 外部 RAM
LOOP_1ms: SUB.W #1,R0 ; 4:12
BNE LOOP_1ms ; 4:12
回数が0になるまで1msウェイト処理へ。
SUB.W #1,E0 ; 4:12
BNE WAIT_1ms ; 4:14
呼び出し元へ処理を戻す。
RTS ; 10:26
まとめるとこんな感じになります。
;******************************************************************************
; 1ms ウェイト(25MH で 25000-10)
;
; _Wiat1ms
; 2004/11/06 : 初期バージョン完成
;
; [書式] void Wait1ms(Uint16 wait) ;
;
; [IN] wait = ウェイト値(ms)
;
; [OUT] なし
;
; [DED] ER0
;******************************************************************************
public _Wait1ms
public WAIT_1ms
_Wait1ms: MOV.W @(4,ER7),E0 ; 6:14 E0 = wait
WAIT_1ms:
MOV.W #3120,R0 ; 4:12 ROM か 内蔵 RAM
; MOV.W #1038,R0 ; 4:12 外部 RAM
LOOP_1ms: SUB.W #1,R0 ; 4:12
BNE LOOP_1ms ; 4:12
SUB.W #1,E0 ; 4:12
BNE WAIT_1ms ; 4:14
RTS ; 10:26