PICのC化 その2
今は,ステップモーターの制御プログラムのC化を手がけていますが,なかなか難しいです.パルスをジッタがないように発生させるために,タイマー割り込みを使っています.
まず,序の口ですが,
label1
処理
decfsz ii,1
goto label1
でしたら,
label1:
処理
if ( --ii ) goto label1;
でいいのですが,
label1
処理
decfsz ii,0
goto label1
だと,
label1:
処理
if ( ii-1 ) goto label1;
としないといけません.0と1の違いで^^; 解ってはいますが,ちょっと見ただけじゃなかなか間違いを見つけられません.
これだけならそんなに難易度は高くありませんが(といいつつ,気がつくまでかなり時間がかかりました),こういうのが複合して攻めてきますので,なかなか正解にたどり着けません.
本日の極めつけは,SDCCのbugというか仕様です.
while( 1 ) {
ii=1;
jj=2;
if ( RB1 ) break;
}
です.毎回,iiとjjに新鮮な1と2を送り込みながら,RB1がHになるのを待つルーチンです.これしきのことがなかなか動いてくれなくて,生成されたアセンブリ言語を見たら,なんと,ii, jjへの代入は,1度だけで,RB1の読み込みのみでループしています.
確かに,これだけ見れば,毎回いちいちii, jjに定数を代入する必要はないですが,割り込みルーチンが,ii, jjを書き換えるので,常に新鮮な1, 2にする必要があるのです^^;
部分的に最適化を止める方法があるのかどうか解りませんので,
while ( 1 ) {
_asm
movlw 1
movwf _ii
movlw 2
movwf _jj
_endasm;
if ( RB1 ) break;
}
として解決しました^^;
生成されたプログラムのサイズは,2.5倍で,16F84(A)の0x3FFまででは,残りわずかです.
ただし,オリジナルのアセンブリ言語ではEEPROM領域に入れていた,パルス発生タイミングのテーブルがプログラム領域に展開されているので,この2.5倍がまるまるコンパイラーのできの悪さではないです.いや〜,それも含めてコンパイラのできを考えるべきかも^^;
機能を拡張するためには,16F84Aより安い^^; 16F88に移植する必要があります.
- Category(s)
- PIC
- PICのC化
- ¦
- Main
- ¦
- PICのC化 その3