情報処理の講義でArduinoのレジスタを触り始めたのですが、解説が絶望的なのでクラスの誰か一人でも救済できたらいいなと思って書いた記事です。
Arduinoとは
ATmega328Pというマイコンが載っている基板のことです。マイコンの入出力ピンがそのままピンソケットにつながっているって解釈して問題ないです。マイコンをジャンプワイヤー刺しやすくしましたみたいな。
Arduino言語やめろ
Arduino言語とかいうあたかも別言語が登場したかのように講義では扱われてますが、この解釈かなり危険なのでマジでやめた方がいいです。基本的にただのC言語1です。
Arduino IDE上では省略されていますが、内部では
#include <Arduino.h>
が記述されています。普段、プログラムの先頭に
#include <stdio.h>
してprintf()
とかが使えるようにするのと同じように、Arduino.h
をincludeしてpinMode()
やdigitalWrite()
を使えるようにしてるだけです。
で、stdio.h
をincludeしたからといってstdio言語って言わないですよね?なのでArduino言語って言うのは良くない(というよりキモい)と言うわけ。
まとめると講義中に言われている
Arduino言語ではなくC言語で記述しなさい
は表現として適切ではなく、
Arduino.hで定義されている関数を使うな
と解釈するのがいいと思います。
要するにprintf()
を使わずに文字を画面に表示しろって言われてるのと立ち位置は完全に一緒です。多分(知らんけど)メモリ操作をゴリればprintf()
を使わずに文字列を出力できると思います。
それと同じであの先生はdigitalWrite()
を使わずにLEDチカチカしろと俺たちに言っています。ただの縛りプレイが科されているだけです。
-
Arduino.h
というものが内部に存在する。 -
Arduino.h
があろうとなかろうとC言語であることに変わりはない - ただの
digitalWrite()
とpinMode()
禁止縛り
レジスタ操作のトリック
ポートレジスタはピンの状態を表す変数です。pinMode()
やdigitalWrite()
はポートレジスタを簡単に操作するための関数です。
なので、ポートレジスタを直接操作できるプログラム力があるならpinMode()
やdigitalWrite()
がなくても問題ないという理論です。マジでやめた方がいい
Arduinoには3つのポートがあり、1ポートあたり最大8ピンを操作できます。
- ポートB : D8からD13
- ポートC : A0からA5
- ポートD : D0からD7
が割り当てられています。
それぞれのポートには3つのレジスタ変数があります。(にはB, C, Dが入ります)
レジスタ変数 | 役割 |
---|---|
DDRX | 入出力方向の設定レジスタ。pinMode() に対応 |
PORTX | 出力レジスタ。digitalWrite() に対応 |
PINX | 入力レジスタ。digitalRead() に対応 |
例としてDDRXについて記します。PORTX, PINXについても同様です。
例えばDDRDを操作してPD6だけを出力ピン、ポートDの他のピンを入力にするためには
DDRD = 0B01000000;
とします。0B
は2進数表記であることを示す記号です。
レジスタのメリット
例えば、8番ピン(PB0)と9番ピン(PB1)をHIGHに設定したい時、普通は
digitalWrite(8, HIGH);
digitalWrite(9, HIGH);
としますが、プログラムは上から下へ流れるのでこれだと8がHIGHになった後に9がHIGHになります。ほんとに数[ns]のお話ですが、遅れることは遅れます。
レジスタ操作を使うと
PORTB = 0B00000011;
と書けます。これなら8と9を同時にHIGHにできます。
レジスタのデメリット
- シンプルにプログラムが読みにくい
- 沼ったら数[ns]節約するために、デバッグに数時間食われる
ほとんどの場合デメリットの方が大きいと思うので、普段はdigitalWriteとかを使うのが推奨です。なんかかっこいいからとかすごそうだからのノリで使うべきではない気がします。
次回予告
- 具体的なレジスタ操作
- ピンを個別で設定する方法(ブール代数)
-
正確にはC++言語ですが、C++は基本的にCの機能を含んでいるので、この講義中はC言語と解釈してしまって問題ないです。 ↩