PICでC言語

とある方面の依頼で、PIC12F675でサーボモータを制御するプログラムを作ることに。C言語で開発した方が早そうだったので、「C言語ではじめるPICマイコン―フリーのCコンパイラではじめよう」を参考に、プログラムをHI-TECH PICC Liteで作ってました。Bankなんかを意識しなくていいし、慣れたC言語で書けてかなり楽。ただ、やはりアセンブラに比べると効率の悪いプログラムになってしまいがちです。

サーボモータ制御プログラムを書く前に、C言語での開発と、動作速度についての検証としてテストプログラムを書きました。以下は255回、NOP(何もしない)を実行するテストプログラムです。for文を使ったもの、while文を使ったもの、アセンブラで書いたものの3種類を用意したところ、その実行時間はC言語で書いたものが358[usec]、アセンブラが204[usec]でした(20MHz動作)。for文とwhile文の違いはほとんどありません。

#include 

unsigned char i;
unsigned char loop = 0xff;

void main( void )
{
  for ( i = 0; i != loop; i++ ) {
    asm("NOP");
  }

  i = loop;
  while( i ) {
    asm("NOP");
    i--;
  }
  
#asm
  MOVF _loop,W
  MOVWF _i
test_loop:
  NOP
  DECFSZ _i,f
  GOTO test_loop
#endasm
}

注意点ですが、ループ変数にintを使うと処理時間が倍ぐらいになります。というのも、PICでは普通1命令で扱うのが8bitなのですが、PICCのintが16bitなためです。確かintの大きさって、その処理系で効率のよいサイズということになってたはずなので、最初勘違いして全部intでやってました。ちなみにintを使った場合、forよりもwhileの方が明らかに速くなります。

C言語で書いたときに遅くなる原因を探すため、逆アセンブルしてソースを眺めてみると、どうもこの手のループ処理によく使うDECFSZ命令を使ってないんですね。このwhile文なんかはそれをかなり意識して書いたつもりだったんですが、よく考えてみれば確かに微妙に違う処理です。

まあそんな感じでいろいろありますが、上の例のように必要に応じてC言語アセンブラを書き分けることもできるわけなので、PICでのC言語開発、おすすめです。