今回もArduinoネタです。
前回の記事のようにArduino Dueをレジスタ直接制御で動かしていきます。
今回はGPIO編です。
・前回記事
前回、軽く触れたようにArduinoのピン配列は以下のようになっています。
Arduino Dueには、色々と番号がふられていますが、レジスタ直接制御を行う場合にはマイコン側のピン番号を使うことになります。
例えば、Arduinoの2ピンであればArduino Due搭載マイコン(ATSAM3X8E)ではB25です。
目次
ArduinoでGPIO出力するための手順
①マイコン機能への電源(クロック)供給
消費電力を抑えるため、マイコンは周辺機能の電源を最初はOFFにしています。
従って、マイコンの各種機能を使用するには、まず電源 (クロック) を供給してやる必要があります。
ATSAM3X8Eのデータシートを見ると以下の様な機能を持っています。
ATSAM3X8Eのデータシート
先ほどのArduinoの2ピン(B25)であればInstance ID(PID) = 12(PIOB)となります。
PIOBへクロックを供給するためには以下のPMC_PCERレジスタに書き込みが必要になります。
PMC_PCERにはPMC_PCER0とPMC_PCER1がありますが、PID = 12はPMC_PCER0側にあります。
クロックの供給が完了すると、次はGPIOの出力をさせるための設定を行います。
以下がPIOポートの概要図です。
GPIOの出力を行うためには、以下のレジスタに値を書き込んでいくことになります。
例えば、PIO Status Register(PIO_PSR[0])に値を書き込む方法
PIO_PER[0]に1を書き込むと、PIO_PSR[0]が1になる。(上側だと"1")
PIO_PDR[0]に1を書き込むと、PIO_PSR[0]が0になる。(下側だと"0")
同様にPIO_OSR, PIO_ODSR, PIO_MDSR, PIO_PUSRも設定し、マイコン端子まで繋いでいきます。
GPIO出力を行うまでのレジスタ設定は以下です。
汎用の入出力機能を使うため、周辺機能は使わないのでPIO_ABSR[0]は無関係です。
ここまでの流れをプログラムに書くと以下です。
B25なのでPIOBで各レジスタの25ビット目に値を書き込むことになります。
ソースコード例
void setup() { // put your setup code here, to run once: PMC->PMC_PCER0 = 1<<12;//PIOB (Peripheral ID:12)にクロックを供給する。 PIOB->PIO_PER = 1<<25;//PSR (PIO Status) を1にする。 PIOB->PIO_OER = 1<<25;//OSR (Output Status) を1にする。 PIOB->PIO_MDDR = 1<<25;//MDSR (Multi-Driver Status)を0にする。 } void loop() { // put your main code here, to run repeatedly: PIOB->PIO_SODR = 1<<25;//PIOB25をHIGHレベルにする。 delay(500);//500ミリ秒待つ。 PIOB->PIO_CODR = 1<<25;//PIOB25をLOWレベルにする。 delay(500);//500ミリ秒待つ。 }
分かりやすくビットシフト演算していますが、直接書き込んだ方が演算処理が無くなるのでより早くなると思います。(1 << 25 ⇒ 0x02000000)
上記を設定することでdigitalWriteをマイコン直接制御で実現することができます。
電子工作で使うだけだと、こんなにマニアックなことはしなくても問題ないと思いますが、高速制御にこだわる人は一度試してはいかがでしょうか。