====== 単純なウェイト処理 ====== ===== ウェイト値の求め方 ===== まず動作クロック(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