12bitAD変換

# はじめに
12bitAD変換の設定諸々についての記述．マイコンボードは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)

# 12bitAD変換の設定
HM 1.5 表1.9より，アナログ値を受け取りたい端子を確認する（例：P40 > AN000）．AD変換の端子は基本的に一括で取り扱う

### 初期化関数
流れ
1. 端子機能設定
2. ADC停止
3. ADCの設定
4. サンプリングレート
5. ADC開始

```c:"hwsetup.c"
void S12ADC_init(void);

void HardwareSetup(void)
{
	S12ADC_init();
}
```
```c:
/*=================================
 * 関数名 : S12ADC0_init
 * 機能 : AN000の初期化
 * 引数 : なし
 * 戻り値 : なし
 * 備考 : 12bitADC
 * ===============================*/
void S12ADC_init(void)
{
	/*=== プロテクト解除 ===*/
    SYSTEM.PRCR.WORD = 0xA502;
    /*=== SCI0を有効化 ===*/
    MSTP(S12AD) = 0;
    /*=== プロテクト ===*/
    SYSTEM.PRCR.WORD = 0xA500;
    /*=== 端子機能の有効化 ===*/
    PORT4.PMR.BIT.B0 = 1;
    /*=== ピン機能設定 プロテクト解除===*/
    MPC.PWPR.BIT.B0WI = 0;
    MPC.PWPR.BIT.PFSWE = 1;
    /*=== ピン機能設定 P20 > AN000 ===*/
    MPC.P40PFS.BIT.ASEL = 1;
    /*=== ピン機能設定 プロテクト===*/
    MPC.PWPR.BIT.PFSWE = 0;
    MPC.PWPR.BIT.B0WI = 1;
    /*=== ADCストップ ===*/
    S12AD.ADCSR.BIT.ADST = 0;
    /*=== クロック選択 : PCLK/8===*/
    S12AD.ADCSR.BIT.CKS = 0x00;
    /*=== トリガー選択 : 同期式 ===*/
    S12AD.ADCSR.BIT.EXTRG = 1;
    /*=== 割り込み禁止 ===*/
    S12AD.ADCSR.BIT.ADIE = 0;
    /*=== スキャンモード : 連続スキャン ===*/
    S12AD.ADCSR.BIT.ADCS = 1;
    /*=== ADCチャンネル設定 : AN000 ===*/
    S12AD.ADANS0.WORD = 0x0001;
    /*=== 加算モード非選択 ===*/
    S12AD.ADADS0.WORD = 0x0000;
    /*=== ADDRy自動クリア ===*/
    S12AD.ADCER.BIT.ACE = 1;
    /*=== データフォーマット : 右詰め ===*/
    S12AD.ADCER.BIT.ADRFMT = 0;
    /*=== サンプリングレート : 30ns ===*/
    S12AD.ADSSTR01.BIT.SST1 = 30;
    /*=== ADC開始 ===*/
    S12AD.ADCSR.BIT.ADST = 1;
}
```

```c:"main.c"
#include"iodefine.h"
#include"name.h"
#include"icu_cmt.h"
#include"sci.h"

void main(void)
{
	unsigned char data[2] = {0,1};
	unsigned short S12ADC0_data;

	while(1)
	{
		S12ADC0_data = S12AD.ADDR0;
		data[1] = (S12ADC0_data >> 8) & 0x00FF;
		data[0] = S12ADC0_data & 0x00FF;
		LED = LED_ON;
		Delay(500);
		SCI0_write(data[1]);
		SCI0_write(data[0]);
		LED = LED_OFF;
		Delay(500);

	}

}
```

### 詳細

#### 初期化関数

##### 1. 端子機能設定
```c
SYSTEM.PRCR.WORD = 0xA502;
```
**プロテクト解除**
HM 13.1.1より，保護するレジスタへの書き込み許可を選択する．`PRCR`は16bit構成で以下のような内容である．`WORD`で一括で設定している．
b0 > 0 :クロック発生回路関連レジスタへの書き込み禁止
b1 > 1 :動作モード、消費電力低減機能、ソフトウェアリセット関連レジスタへの書き込み許可
b2 > 0 :予約ビット
b3 > 0 :LVD関連レジスタへの書き込み禁止
b7-4 > 0 :予約ビット
b15-8 > A5 : PRCキーコードビット 

```c
MSTP(S12AD) = 0;
```
**モジュールストップ解除**
HM 11.4より，レジスタの読み出し書き込みができる状態にする必要がある．`=0`で解除となる．

```c
SYSTEM.PRCR.WORD = 0xA500;
```
**プロテクト**
HM 13.1.1より，保護するレジスタへの書き込みを禁止する．

```c
PORT4.PMR.BIT.B0 = 1;
```
**端子機能の有効化**
HM 1.5 表1.10より，必要な機能が備わっている端子を選定する．HM 21.3.4より，`=1`で端子機能を有効化する．

```
MPC.PWPR.BIT.B0WI = 0;
MPC.PWPR.BIT.PFSWE = 1;
```
**ピン機能設定 プロテクト解除**
HM 22.2.1より，初めに`B0WI = 0`でPFSWEレジスタへの書き込みを許可する．次に，`PFSWE = 1`でPFSレジスタへの書き込みを許可する．許可順番は必ず守る．

```
MPC.P40PFS.BIT.ASEL = 1;
```
**ピン機能設定**
HM 22.2.6より，周辺機能を設定する．ここでは，`ASEL=1`でP40をアナログ端子として設定している．

```
MPC.PWPR.BIT.PFSWE = 0;
MPC.PWPR.BIT.B0WI = 1;
```
**ピン機能設定 プロテクト**
HM 22.2.1より，順次プロテクトする．プロテクト順番は必ず守る．

##### 2. ADC停止

```c
S12AD.ADCSR.BIT.ADST = 0;
```
HM 41.2.1 より，ADCを禁止する．

##### 3. ADCの設定
```c
S12AD.ADCSR.BIT.CKS = 0x00;
```
**クロック選択**
HM41.2.1 より，クロックを選択する．`CKS=0x00`でPCLK/8となる．

```c
S12AD.ADCSR.BIT.EXTRG = 1;
```
**トリガー選択**
HM41.2.1 より，ADCを開始するトリガーを選択する．`=1`でクロック同期式となる．外部入力をトリガーにする場合は非同期式を選択する．

```c
S12AD.ADCSR.BIT.ADIE = 0;
```
**割り込み禁止**
HM41.2.1 より，`=0`でスキャン後の割り込みを禁止する．割り込みする場合は，`=1`として，vect.h内の`#pragma interrupt (Excep_S12AD_S12ADI0(vect=102))`を変更する．また，以下のように割り込み許可と優先度設定を行う必要がある．

```c:"hwsetup.c"
/*=== 割り込み許可 ===*/
IEN(S12AD, S12ADI0) = 1;
/*=== 割り込み優先度設定 ===*/
IPR(S12AD, S12ADI0) = 8;
```

```c
S12AD.ADCSR.BIT.ADCS = 1;
```
**スキャンモード**
HM41.2.1 より，`=1`で連続スキャンモードとする．シングルスキャンは本当に1回分のみの読み込みとなる．

```c
S12AD.ADANS0.WORD = 0x0001;
```
**ADC変換チャンネル設定**
HM41.2.2 より，使用するAN***分だけ変換対象とする．

```c
S12AD.ADADS0.WORD = 0x0000;
```
**加算モード**
HM41.2.4 より，加算モードを非選択とする．選択すると，チェックサムらしきものがアナログ値に追加される．

```c
S12AD.ADCER.BIT.ACE = 1;
```
**自動クリア**
HM41.2.7 より，`=1`でADDRyレジスタを自動でクリア`0`とする．未更新故障の防止となる．

```c
S12AD.ADCER.BIT.ADRFMT = 0;
```
**データフォーマット**
HM41.2.7 より，`=0`で2byteデータに対して右詰めでデータが送られるようになる．

##### 4. サンプリングレート
```c
S12AD.ADSSTR01.BIT.SST1 = 30;
```
HM41.2.13 より，10～255ステートのステート単位にサンプリング時間を設定する．デフォルト値は20．
1 ステート＝ 1ADCLK（`S12AD.ADCSR.BIT.CKS`で設定した分周クロック）
サンプリング時間 = SST1(ステート数) x 1 ステート

##### 5. ADC開始
```c
S12AD.ADCSR.BIT.ADST = 1;
```
HM 41.2.1 より，ADCを開始する．

#### アナログ値読みこみ
HM41.2.12 より，ADDRyにアナログ値が格納される．このレジスタは2byteである．必要に応じてビット演算を行い取り扱いやすいようにする．

12-bit の場合，3.3V=0xFFFであるので注意する．

# 参考文献
- RX631開発 12bit ADC https://blog.ccwo.net/entry/2016/08/18/025727
- S12ADC　：　RX63N http://pgstudynotes.blogspot.com/2017/05/s12adcrx63n.html
- A/D変換の概要 http://memes.sakura.ne.jp/memes/?page_id=1120
- ビット演算 https://www.binzume.net/library/robo/ca3.html
- RXファミリ ADCモジュール Firmware Integration Technology アプリケーションノート https://www.renesas.com/jp/ja/doc/products/tool/apn/001/r01an1666jj0420-rx-adc.pdf