具体的には,printfの文字列送信にかかる時間と受信エラーの処理についてです。
ターゲットマイコンは,これまで同様SH7125,HEWとコンパイラパッケージは,
- C/C++ compiler package for SuperH RISC engine family V.9.04 Release 01
- High-performance Embedded Workshop Upgrade 4.09.01
です。まあ前回とほとんど変わってないんですが,念のため。
1. 文字列の送信には割と時間がかかる
これまでに,printf用の低水準入出力関数を作ることで,文字列をシリアル通信経由で,PCの画面に表示させました。このため,出力する文字が増えるほど,表示に時間がかかります。また,printfでは,変数の値を指定したフォーマット(%dとか%fとか)に変換する処理も必要なので,シリアル通信の通信時間+αの時間がかかるわけです。
出力文字数とフォーマットを変えて,どれだけ時間がかかるか測定してみました。
表示にかかる時間は,こんな感じ↓で,printfを行うたびにデバッグ用LEDを点滅させ,その時間をオシロで測りました。シリアル通信の通信速度は38400 bpsです。
int i;
int a;
a=12345;
while(1){
led_on();
printf("%d",a);
led_off();
printf("%d",a);
}
|
表示速度測定中・・・ |
出力文字数と表示にかかった時間との関係(38400 bps) |
浮動小数点型のほうが表示に時間がかかるようです。また,char,short,intはそれぞれ1 byte,2 byte,4 byteですが,表示にかかる時間は同じでした。
ロボットの制御などで,短い周期でprintfを使う場合は注意が必要です。
2. 受信エラー処理付きcharget
最近,シリアル通信で連続して送られてくるデータをSHで受信しようとしたのですが,なかなか上手くいかず・・・- -;これは,charget関数に受信エラー処理がなかったことが原因でした。
修正したcharget関数は下表のとおりです。ハードウェアマニュアルのp.412あたりに受信処理のフローチャート例が載っており,参考にしました。最初からちゃんとハードウェアマニュアル読んでおけばよかったのですが・・・。
char charget(void){ char c; do{ // オーバーランエラーチェック if(SCI1.SCSSR.BIT.ORER == 1){SCI1.SCSSR.BIT.ORER = 0;} // とりあえずクリアしておく // フレーミングエラーチェック if(SCI1.SCSSR.BIT.FER == 1){SCI1.SCSSR.BIT.FER = 0;} // とりあえずクリアしておく // パリティエラーチェック if(SCI1.SCSSR.BIT.PER == 1){SCI1.SCSSR.BIT.PER = 0;} // とりあえずクリアしておく }while(SCI1.SCSSR.BIT.RDRF == 0); c = SCI1.SCRDR; SCI1.SCSSR.BIT.RDRF = 0; return(c); } |
SH7125は3つの受信エラーを検出でき,受信エラーフラグがセットされている間は受信を停止します。以前のchargetはエラーフラグをクリアしていなかったため,一度受信エラーが起こった後にchargetを呼ぶと戻ってこなくなるという,かなりひどい問題がありました^^;
シリアルでデータが連続して送られてくる場合(GPSや各種センサを使う場合)は,特に注意が必要です。
私の場合,「sci初期化」から「最初のcharget」の間に送られてきたデータでオーバーランエラーを起こしていたようです…
↑のchargetは,受信エラーフラグを(とりあえず)クリアすることで,(とりあえず)受信を続けるようになっています。
また新しい発見があれば,追記していきたいと思います。
それでは -_-)ノシ
0 件のコメント:
コメントを投稿