CCWO Embedded Space

CCWOの日々の開発を発信するブログ

Renesas RX621 12bitADC

12bitADCの設定をしていきたと思います。
12bitADCとは12bit Analog Digital Converterの略で、マイコンのAVDDとAVSS間に印加された電圧を基準に、ピンに印加された電圧を12bitのディジタル値に変換することができます。
これにより、アナログ電圧を出力するセンサー等の値をマイコンで扱えるようにすることができます。
ここで、RX621では8chの12bitADCがあるのですべてを使いたいと思います。
それでは、S12AD機能を用いて、AD変換の設定をしていきたいと思います。
まず、e2 stduio左側プロジェクトエクスプローラのプロジェクトフォルダ内のsrcフォルダを右クリックし,
新規→ソース・ファイルからS12AD.c
新規→ヘッダ・ファイルからS12AD.h
を作成します。
ソースコードの追加はプロジェクトファイルのsrcフォルダに直接作成することでも可能です。
つぎに、hardware_setup.cにてS12AD.hをインクルードし、HardwareSetup関数でS12AD.cのS12AD_initialize関数を呼びます。

S12AD.h

#ifndef S12AD_H_
#define S12AD_H_

extern unsigned short ADC12[8];

void S12AD_initialize(void);

#endif /* S12AD_H_ */

S12AD.c

#include "iodefine.h"
#include "machine.h"
#include "vect.h"

#pragma interrupt (S12AD_ADI_interrupt(vect=VECT(S12AD, ADI)))

unsigned short ADC12[8];

void S12AD_initialize(void){
	MSTP(S12AD) = 0;				// Wake up S12AD
	S12AD.ADCSR.BIT.EXTRG = 0;		// Trigger = ADSTRGR: Software Trigger
	S12AD.ADCSR.BIT.CKS = 0;		// PCLK/8
	S12AD.ADCSR.BIT.ADIE = 1;		// Enable S12ADI0
	S12AD.ADCSR.BIT.ADCS = 1;		// Continuous scanning
	S12AD.ADCSR.BIT.ADST = 0;		// Stop S12AD
	S12AD.ADANS.WORD = 0xFF;		// S12ADC: AN0-7
	S12AD.ADADS.WORD = 0x00;		// Disable ADD result Mode
	S12AD.ADCER.BIT.ACE = 1;		// Auto clearing
	S12AD.ADCER.BIT.ADRFMT = 0;		// Right -justified
	S12AD.ADCSR.BIT.ADST = 1;		// Start S12AD
	IPR(S12AD, ADI) = 6;			// Interrupt level6
	IEN(S12AD, ADI) =1;				// Enable ADI interrupt
}

void S12AD_ADI_interrupt(void){
	ADC12[0] = S12AD.ADDR0;
	ADC12[1] = S12AD.ADDR1;
	ADC12[2] = S12AD.ADDR2;
	ADC12[3] = S12AD.ADDR3;
	ADC12[4] = S12AD.ADDR4;
	ADC12[5] = S12AD.ADDR5;
	ADC12[6] = S12AD.ADDR6;
	ADC12[7] = S12AD.ADDR7;
}

つぎに、vect.hの

// S12AD ADI
#pragma interrupt (Excep_S12AD_ADI(vect=102))
void Excep_S12AD_ADI(void);

をすべてコメントアウトします。
また、メイン文にて
main関数

#include "iodefine.h"
#include "machine.h"
#include "S12AD.h"
#include <stdio.h>

void main(void)
{
	static unsigned int i;
	while(1){
		printf("ADC[0]:%4d\tADC[1]:%4d\tADC[2]:%4d\tADC[3]:%4d\nADC[4]:%4d\tADC[5]:%4d\tADC[6]:%4d\tADC[7]:%4d\n", ADC12[0],ADC12[1],ADC12[2],ADC12[3],ADC12[4],ADC12[5],ADC12[6],ADC12[7]);
		for(i = 0; i < 65000; i++) nop();
	}
}

などと、記述してデバッグを行いましょう。おそらく値が震えているはず。その状態で成功となります。
No Connection Pin(未処理ピン)は、Hi-Z状態のため値が震えます。

それではS12ADの設定手順をみていきます。

  1. モジュールスタート(消費電力低減機能の解除)
  2. ピンの設定
  3. S12ADの設定
  4. ユーザ関数の定義

1.モジュールスタート(消費電力低減機能の解除)

MSTP(S12AD) = 0;		// Wake up S12AD

消費電力低減機能を解除します。RX631のようにアクセスロックはないので、そのまま解除します。
MSTPCTRレジスタがiodefine.hでMSTP(****)というようにデファインされているのでこれを使用します。

2.ピンの設定
S12AD設定内でchを有効にすると自動的にS12ADにピンは接続されます。

3.S12ADの設定

S12AD.ADCSR.BIT.EXTRG = 0;		// Trigger = ADSTRGR: Software Trigger
S12AD.ADCSR.BIT.CKS = 0;		// PCLK/8
S12AD.ADCSR.BIT.ADIE = 1;		// Enable S12ADI0
S12AD.ADCSR.BIT.ADCS = 1;		// Continuous scanning
S12AD.ADCSR.BIT.ADST = 0;		// Stop S12AD
S12AD.ADANS.WORD = 0xFF;		// S12ADC: AN0-7
S12AD.ADADS.WORD = 0x00;		// Disable ADD result Mode
S12AD.ADCER.BIT.ACE = 1;		// Auto clearing
S12AD.ADCER.BIT.ADRFMT = 0;		// Right -justified
S12AD.ADCSR.BIT.ADST = 1;		// Start S12AD

S12ADはデータシートに初期化手順が示されているわけではないので、今回は連続スキャンモードを参考に設定していきます。
しかし、ここで余談ですが、RXに限らずマイコンのAD変換の設定はおおまかに
・AD変換クロックの設定(モジュールの動作周波数の設定)
・トリガ、割り込みの設定(AD変換のトリガの設定)
・AD変換chの設定(何個AD変換を使用するの設定)
・加算、フィルタの設定(精度を上げたりするための設定)
・データ型の設定(右詰め、左詰め(Little,Big Endian=Byte-order)の設定)
・サンプリング周期の設定(AD変換には一般的にある程度の時間を要さないと構造的に精度が出ないためサンプリング時間の設定をする。)
RX621もほぼ例に漏れることなく設定していく。
つぎに、タイマー割り込み同様に割り込みの設定をする。

IPR(S12AD, ADI) = 6;	// Interrupt level6
IEN(S12AD, ADI) =1;	// Enable ADI interrupt

4.ユーザ関数の定義

#include "vect.h"

#pragma interrupt (S12AD_ADI_interrupt(vect=VECT(S12AD, ADI)))

void S12AD_ADI_interrupt(void){
	ADC12[0] = S12AD.ADDR0;
	ADC12[1] = S12AD.ADDR1;
	ADC12[2] = S12AD.ADDR2;
	ADC12[3] = S12AD.ADDR3;
	ADC12[4] = S12AD.ADDR4;
	ADC12[5] = S12AD.ADDR5;
	ADC12[6] = S12AD.ADDR6;
	ADC12[7] = S12AD.ADDR7;
}

ベクタ番号=VECT(S12AD, ADI)でS12AD_ADI_interrupt関数が呼ばれるようにpragmaにて設定をします。
これでS12ADの設定は完了です。割り込みを使用しない場合はS12AD.ADDR0~7に値が入っているのでこれをタイマー割り込み等でバッファするのがいいかと思います。

20160822の記事