汎用I/Oポート(GPIO)

# はじめに
汎用I/Oポート(GPIO)の設定諸々についての記述．マイコンボードはGR-CITRUSとする．ハードウェアマニュアルの参考先はHM ＊.＊.＊と表記する（例：HM 3.3.4ならばハードウェアマニュアルの3.3.4節を参考）．

資料（必需品）
・ [RX63Nグループ、RX631グループ ユーザーズマニュアル](https://www.marutsu.co.jp/contents/shop/marutsu/datasheet/R5F563.pdf)
・ [GR-CITRUS回路図](https://www.renesas.com/jp/ja/doc/gr/gr-citrus/citrus-1.0.pdf)

# 汎用I/Oポート(GPIO)とは

デジタル信号の出力をしたり，入力情報を確認する役割を持つ．
流れとしては，以下をレジスタを用いて設定をする．

1. 任意端子を入力するか出力するかの決定する(ポート方向レジスタ PDR)．出力端子はデジタル信号を出力することができる．入力端子は入力されているデジタル信号の状態を見ることができる．
2. 出力ならば，出力端子の状態を決定する(ポート出力データレジスタ PODR)．入力ならば，入力端子の状態を確認する(ポート入力データレジスタ PIDR)．

![IOport_image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520158/3950fc75-da23-c1a3-4b61-357c8aae427f.png)

# 端子の入出力設定
hwsetup.cにあるHardwareSetup関数にプログラムする．

### 出力

回路図より，PA0を出力とする．PA0は，PORTA BIT0の意味．ポートの種類は，HM 1.5 の機能別端子一覧を参照．

![ioP_LED.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520158/5db1475a-6b47-e87f-7f0a-35ef7fb8c2bb.png)

```c:"hwsetup.c"
extern void HardwareSetup(void);
void GPIO_init(void);

void HardwareSetup(void)
{
	GPIO_init();
}
```

```
/*=================================
 * 関数名 : GPIO_init
 * 機能 : IOポートの初期化
 * 引数 : なし
 * 戻り値 : なし
 * 備考 :
 * ===============================*/
void GPIO_init(void)
{
	PORTA.PDR.BIT.B0 = 1; //LED
}
```

HM21.3.1より，入出力設定をPDR（ポート方向レジスタ）で行う．各ポートは，B0～B7の1byteで構成されている．`PORTA.PDR.BIT.B0`は，＜`PORTA`を方向決定(`PDR`)します．1`BIT`分設定で，`B0`を出力端子(`=1`)として使う＞の意味．1byteまとめて設定する時は`BYTE`を用いる．例：`PORTA.PDR.BYTE = 0x01``PORTA.PDR.BYTE = 00000001`

```c:"HelloWorld.c"
#include"iodefine.h"

void main(void)
{
	PORTA.PODR.BIT.B0 = 1;
}
```
HM21.3.2より，出力状態の指定をPODR（ポート出力データレジスタ）で行う．`PORTA.PODR.BIT.B0`は，＜`PORTA`を出力状態決定（`PODR`）します．1`BIT`分設定で，`B0`を出力状態hight(`=1`)にします．＞の意味

```c:"HelloWorld.c"
#include"iodefine.h"
#define LED PORTA.PODR.BIT.B0
#define LED_ON 1

void main(void)
{
		LED = LED_ON;
}
```
マクロ定義を用いると見やすくなる．

↓もっと短く書く方法

```c
#define LED_ON PORTA.PODR.BIT.B0=1
#define LED_OFF PORTA.PODR.BIT.B0=0

void main(void)
{
	LED_ON;
}

```

### 入力
回路図より，PC0を出力とする．GR-SALIRAの回路図を参考にしてスイッチ回路を作成する．この回路では，スイッチを押していない時に端子への入力がhight，押している時にlowになる．

![ioP_SW2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520158/fee5f4a4-18ee-a14b-e492-f2505e1857e9.png)

```c:"hwsetup.c"
extern void HardwareSetup(void);
void GPIO_init(void);

void HardwareSetup(void)
{
	GPIO_init();
}

void GPIO_init(void)
{
	PORTA.PDR.BIT.B0 = 1; //LED
    PORTC.PDR.BIT.B0 = 0; //Switch
}

```

HM21.3.1より，入出力設定をPDR（ポート方向レジスタ）で行う．`PORTC.PDR.BIT.B0`は，＜`PORTC`を方向決定(`PDR`)します．1`BIT`分設定で，`B0`を入力端子(`=0`)として使う＞の意味．

```c:"HelloWorld.c"
#include"iodefine.h"
#define LED PORTA.PODR.BIT.B0
#define LED_ON 1
#define LED_OFF 0

void main(void)
{

while(1)
{

	if(PORTC.PIDR.BIT.B0 == 0)
	{
		LED = LED_ON;
	}else{
		LED = LED_OFF;
	}

}

}
```

HM21.3.3より，入力状態をPIDR（ポート入力データレジスタ）で行う．`PORTC.PIDR.BIT.B0`は，＜`PORTC`を入力状態の確認（`PIDR`）します．1`BIT`分，`B0`を確認します．0ならlow，1ならhightです．＞の意味．このプログラムの場合は，PC0がlow（スイッチを押している状態）ならば，PA0がhight（LEDが点灯）になる．

↓もっと短く書く方法

```c
#define LED_ON PORTA.PODR.BIT.B0=1
#define LED_OFF PORTA.PODR.BIT.B0=0

#define SW PORTC.PIDR.BIT.B0
#define SW_ON PORTC.PIDR.BIT.B0=0
#define SW_OFF PORTC.PIDR.BIT.B0=1

void main(void)
{

while(1)
{

	if(SW_ON)
	{
		LED_ON;
	}else{
		LED_OFF;
	}

}

}

```

# 参考文献

- RX631開発 I/O - CCWO https://ccwo.hatenablog.jp/entry/2016/08/18/004505
- GPIO | ルネサス エレクトロニクス https://www.renesas.com/jp/ja/support/technical-resources/engineer-school/mcu-programming-peripherals-01-gpio.html