だるしむダイアリー

ゆるーくマイペースに

男性育児休暇 Arduino Dueを使い倒す ~レジスタ直接制御GPIO編#2

前回はArduino Dueをレジスタ直接制御にてGPIO出力を行いましたが、今回は入力を行っていきます。

 

・前回記事はコチラ

na-daru.hatenablog.com

 

GPIO入力なのでArduinoのwrapperで言うとdigitalreadです。

外部からの入力に対してHi/Loを返します。

また次回書こうと思いますが、割り込み時のトリガーとして使うことが多いです。

 

目次

レジスタ直接制御にてGPIO入力を行う手順

おなじみのArduino Dueのピン配列です。

前回はArduinoの2pin(PIOB25)のGPIO出力を行うためのプログラムを作成しましたが、今回は、3Pin(PIOC28)で入力として受けて結果を表示するプログラムを作成します。

 

GPIOの入力は以下のPIO_PDSR(Pin Data Status Register)で"1","0"管理されます。

なので、前回のGPIOの時と同様に関連するレジスタの設定を行います。

データシートから抜粋しました。

PIO出力設定の部分は前回の記事で設定した出力設定のレジスタ部です。今回は入力設定なので無視です。

設定する必要があるのはPIO_PUSR, PIO_IFSCR, PIO_IFSRの3種類です。

PIO_PUSRはプルアップ抵抗の有効、無効

PIO_IFSCR, PIO_IFSRは内部フィルタの設定関係です。

PIO_PUSRはプルアップ有効、内部フィルタの設定は用途に応じて設定すればいいと思います。

 

今回は以下のように設定しました。

内部フィルタも有効とし、除去するスパイクノイズ幅はMCK(84MHz)としています。

ソースコード

前回のGPIO出力に対してGPIO入力のコードを追加した形になります。

Arduino Dueの2pin, 3pinをショートさせてプログラムを実行します。

(入力で使用する3PinはPIOCなのでPID = 13にクロックの供給も行う必要があるので注意!)

		    
void setup() {
  // put your setup code here, to run once:
  Serial.begin(250000);//シリアル通信開始 (250kbps)
  PMC->PMC_PCER0 = (1<<12) + (1<<13);//PIOB,PIOCにクロックを供給。
  PIOB->PIO_PER = 1<<25;//PIOB25を汎用入出力端子として使う。周辺機能OFF。
  PIOB->PIO_OER = 1<<25;//PIOB25の出力を許可する。
  PIOC->PIO_PUER = 1<<28;//PIOC28のプルアップ抵抗を有効にする。
  PIOC->PIO_SCIFSR = 1<<28;//PIOC28の内部フィルタ選択クロックをMCKにする。
  PIOC->PIO_IFER = 1<<28;//PIOC28の内部フィルタを有効にする。
}

void loop() {
  // put your main code here, to run repeatedly:
  int theLogicVoltage;
  PIOB->PIO_SODR = 1<<25;//PIOB25(2番端子)からHIGH電圧を出力。
  delay(1);
  theLogicVoltage = (PIOC->PIO_PDSR >> 28)&1;//PIOC28の電圧を読み取り※
  Serial.println(theLogicVoltage);//読み取った電圧をシリアル出力
  delay(999);
  
  PIOB->PIO_CODR = 1<<25;//PIOB25(2番端子)からLOW電圧を出力。
  delay(1);
  theLogicVoltage = (PIOC->PIO_PDSR >> 28)&1;//PIOC28の電圧を読み取り※
  Serial.println(theLogicVoltage);//読み取った電圧をシリアル出力
  delay(999);
}

このプログラムを実行すると約1秒ごとにHi/Loが切り替わり、シリアルモニタに出力されます。

3pin(PIOC28)の電圧レベル情報はPIOCのPIO_PDSRレジスタの28ビット目に格納されているのでレジスタにアクセスし、ビットシフトして値を取り出しています。

 

今回でGPIO入出力の設定が出来る様になったので、次回は割り込み機能を使っていきたいと思います。