AVRの実ピン番号からポート入出力の操作

avr(ここではATMEGA88)でピンの入出力を操作するときは、DDRxやPORTx,PINxのレジスタを操作しますが、それと実際のICのピン番号とは一致しておらず、また、順番に並んでいるわけでもありません。

一方で、arduinoでは、
pinModeやdigitalWriteはピン番号を引数としています。

arduinoの方法を端的に説明すると、
arduinoのピン番号順に関連レジスタのアドレスを並べた配列がROMに保存してあり、それを読みだして、ピン番号番目の配列を要素を操作すれば、ピン番号でポートを操作できるという流れです。

pins_arduino.h

Arduino.h

digitalPinToPort
とか参照

  当初、switch文でピン番号から操作するレジスタを分けようとしていたのですが、毎回ピン数に比例した処理をする羽目になるので、arduinoを参考に新しく実装してみました。

BIT_CTRL.cpp

arduinoではROMに配列情報を記していますが、私の場合、DDR,PORT,PIN,bitMaskを一つの構造体にして、ピン番号順に配列にしています。

そのため、digitalWriteに相当する関数が

void pinOutput(uint8_t pinNum, uint8_t output){
  pinNum-=1;    //pin番号は1から始まるため
  if(output==OUTPUT_HIGH){
    *(avrPins[pinNum].port) |= (avrPins[pinNum].pinMask);
  }
  else{
    *(avrPins[pinNum].port) &= ~(avrPins[pinNum].pinMask);
  }
}

となっています。こちらのほうが分かりやすくないでしょうか。まあ、arduinoと大して変わらないのですが... 処理も大して遅くならなかったので、こちらを使いたいと思います。