こんにちは。マイコン初心者です。
R8C/15を使ってLEDの点灯を繰り返そうと思っています。Timerを使わずに、ソフトウェアタイマ(for文のカウントアップで、wait時間を作ろうと考えていました。例えば1msecの時間をfor文で作ろうと思い、20Msecのクロック選択なので、20MHzのクロックなので、1/20M=50nsecとなり、20000倍にすれば1msec近くになると思っていました。しかし、サイクル数のシュミレーションをみると、32768サイクル(約20msec)という結果になっていました。。。単純に20msec/32768=610nなので1.6MHzがサイクル周波数となっています。またシミュレータ同様にオシロでポートのON/OFFをオシロで確認すると、20msecぐらいかかっています。クロックは初期化で20MHzに設定していると思うのですが、何が原因は考えらますでしょうか?お手数ですがアドバイスいただけると幸いです。
参考までにプログラム(開発環境はHEW4.0)と実行時間結果の様子をのせておきます。デバッガーが原因かと思い切り分けを行うためにRUNモードでも確認しましたが動作は同じになりました。
R8CデータシートURL:http://documentation.renesas.com/doc/products/mpumcu/rjj09b0176_r8c14hm.pdf
作成プログラム↓
======================================================#include "sfr_r815.h"
// メインクロック切替関数 20MHzvoid set_MainCLK(void){ prc0 = 1; // プロテクト制御(書き換え許可) cm13 = 1; // Xin-Xout端子切り替え cm05 = 0; // Xin-Xoutメインクロック発振 cm06 = 0; // 8分周以外(分周なし) asm("nop"); // 発振の安定待ち asm("nop"); // (同上) asm("nop"); // (同上) asm("nop"); // (同上) ocd2 = 0; // メインクロック選択 prc0 = 0; // プロテクト制御(書き換え禁止)}
//メイン関数 Wait時間の確認 20000回のカウントアップで1msecvoid main(void){ int cnt; set_MainCLK(); pd1_3=1; while(1) { p1_3=0; for(cnt=0; cnt<2000; cnt++); //wait 0.1msec p1_3=1; for(cnt=0; cnt<20000; cnt++); //wait 1msec }
}======================================================
wait時間.pdf
皆様、
アドバイスありがとうございます!!!!
助かりました。
さきほど、アセンブリコードをソフトウェアマニュアルをみてひとつひとつ命令文を確認してみました。
実行サイクルは約18サイクルほどかかっているようです。
このような確認の仕方はただしいのかわかりませんが、for文でのソフトウェアタイマは調整が必要なことが認識できました。
今回はLEDの点灯のためと、今後のLCDモジュールやいろいろと簡易的なmsecのWait関数を作ろうと考えていましたので、
今回の調査によりR8Cを使うときのカウント数は18倍を目安に考えたいと思います。
ちなみに、他のマイコンでもソフトウェアタイマー作るときは同じぐらいの命令サイクルがかかるのでyそうか?
最近よくARMマイコンが記事になったりしているのですが同じようなものなのでしょうか?
コンパイラの出力はコンパイルオプションで変わったりもしますし、いまどきのコンパイラでは最適化で空ループを削除したりもするのでお勧めできる方法ではないです。
時間待ちはアセンブラで書くかインラインアセンブラを使えばコンパイラの最適化の影響は受けなくなるのでまだマシですが。
ryuさん
はい、ARM系マイコンでも同様で、forループを回すには何クロックか必要ですね。