Arduino UnoのI/Oポートを高速に駆動する方法

  Arduinoは、初心者が作りやすく開発時間が短くなる言語を用意しています。マイコンは一つの端子に複数の機能を割り当てていて、利用者はマニュアルを読んで何に使うかを初期設定しますが、Arduinoはその時間さえ省略できます。その反面、プログラムの実行速度が遅い場合があります。

 たとえば、ディジタル・ポート8番を高速にON/OFFするには次のように記述します。delayMicroseconds()はμs単位で時間を指定できる待ち時間関数です。1~3は指定しても正確でないといわれています。

 オシロスコープで観測します。約145kHzです。

高速にI/OをON/OFFする

 Arduino Unoで使われているマイコンATMega328は、16MHzのクロックで動作しています。もう少し高速でI/Oポートを操作したいものです。

 こちらのポート・レジスタの使い方を説明したWebページを参考にプログラムを書きました。

Arduinoのポート

 マイコンATMega328は、I/Oポートが三組あります。公開されているArduino Unoの回路図を見ると、ATMega328のPB0端子は8番につながっています。

マイコンATMega328の端子名 ArduinoI/O名称
PB0 8
PB1 9
PB2 10
PB3 11
PB4 12
PB5 13

 C言語で2進数は0b1111、8進数は0777、16進0xFFFFのように表記をします。2進数はI/Oポートの各ビットを直接表現するのに向いています。

 B0000000 はビット表現です。右端が最下位になります。PORTBの最下位はPB0で8番ピンに相当します。一つ上のPB1は9番ピンです。

 初期設定で、8番と9番ピンを出力にします。

pinMode(8,OUTPUT);
pinMODE(9,OUTPUT);

 loop()では、

8番をLOW,9番をHIGH

 PORTB=B00000010;


8番をHIGH,9番をLOW

 PORTB=B00000001;

を繰り返します。

 実行すると、約2.6MHzというスピードでI/Oポートが高速にON/OFFされていることがわかります。

 デューティが50%になるように記述しました。loop()関数が実行されるときに裏側で動いている命令の実行時間とのバランスで、変な記述になっています。

(2016/9/17) PORTB x;の記述方法は土井滋貴氏に教えていただきました。