A/D (Analog to Digital Converter)

このページでは、おもに10bitのA/Dについて取り上げます。12bitとは異なる点があることに注意してください。

A/Dコンバータの種類

dsPICのA/Dコンバータはデバイスによって異なり、大別すると次の3種があります。ここではType2のA/Dコンバータを例に解説します。

Type 分解能
Resolution
チャンネル数
Channel
変換速度
Conversion speed
ライブラリファイル
Library file
1 12bit 16 100kspsまたは200ksps※1 adc12.h※2
2 10bit 500kspsまたは1Msps adc10.h
3 12 2Msps ?
※1 sps (Sampling Per Second)
※2 dsPIC33FまたはPIC24Hは、adc.h

ライブラリ

ライブラリファイルはadc10.hをインクルードします。

ライブラリはA/Dコンバータの種類によって異なり、誤ったライブラリをインクルードした場合はコンパイルエラーとなります。ただしこのときのエラーは、

error: 'ADC_MODULE_ON' undeclared (first use in this function)
error: 'ADC_IDLE_STOP' undeclared (first use in this function)
error: 'ADC_FORMAT_INTG' undeclared (first use in this function)
 ...

のように、定数が宣言されていないことを通知するのみです。このような結果になる理由は、ライブラリ全体が

#if defined (__dsPIC30F2010__) || defined (__dsPIC30F3010__) || \
    defined (__dsPIC30F4012__) || defined (__dsPIC30F3011__) || \
    defined (__dsPIC30F4011__) || defined (__dsPIC30F6010__) || \
    defined (__dsPIC30F5015__) || defined (__dsPIC30F6010A__) || \
    defined (__dsPIC30F5016__) || defined (__dsPIC30F6015__)
 ...
#endif

のようなプリプロセッサ ディレクティブで囲まれているためです。

関数、マクロ

関数

用途 関数 説明
初期化 OpenADC10 ADCの設定をする
CloseADC10 ADCモジュールを無効にし、割り込みも無効にする
A/D変換 SetChanADC10 入力チャンネルを指定する
ConvertADC10
(StopSampADC10)
A/D変換を開始する
BusyADC10 AD変換の状態を取得する
ReadADC10 ADCバッファレジスタから読み込む
割り込み ConfigIntADC10 ADCの割り込みを設定する
dsPIC30F ADC10 Peripheral Module Library Help

マクロ

マクロ 説明
EnableIntADC  
DisableIntADC  
SetPriorityIntADC  

レジスタ (Register)

  • ADCON1 (A/D CONtrol 1)
  • ADCON2 (A/D CONtrol 2)
  • ADCON3 (A/D CONtrol 3)
  • ADCHS (A/D CHannel Select) … A/Dコンバータからの入力チャンネル
  • ADPCFG (A/D Port ConFiGuration) … ピンのアナログ・デジタル指定
  • ADCSEL (A/D Channel scan SELection) … 自動スキャンに含めるチャンネル
  • ADCBUFn (ADC data BUFfer) … A/D変換結果を格納するバッファ
区分 SFR名 アドレス Bit 15 Bit 14 Bit 13 Bit 12 Bit 11 Bit 10 Bit 9 Bit 8 Bit 7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0 リセット後の値
ADCONx
(制御)
ADCON1 02A0 ADON - ADSIDL - - - FORM<1:0> SSRC<2:0> - SIMSAM ASAM SAMP DONE 0000 0000 0000 0000
ADCON2 02A2 VCFG<2:0> - - CSCNA CHPS<1:0> BUFS - SMPI<3:0> BUFM ALTS 0000 0000 0000 0000
ADCON3 02A4 - - - SAMC<4:0> ADRC - ADCS<5:0> 0000 0000 0000 0000
ADCHS
(チャンネル選択)
ADCHS 02A6 CHXNB<1:0> CHXSB CH0NB CH0SB<3 :0> CHXNA<1:0> CHXSA CH0NA CH0SA<3:0> 0000 0000 0000 0000
ADPCFG
(ポート設定)
ADPCFG 02A8 PCFG15 PCFG14 PCFG13 PCFG12 PCFG11 PCFG10 PCFG9 PCFG8 PCFG7 PCFG6 PCFG5 PCFG4 PCFG3 PCFG2 PCFG1 PCFG0 0000 0000 0000 0000
ADCSEL
(スキャン選択)
ADCSSL 02AA CSSL<15:0> 0000 0000 0000 0000
ADCBUFx
(バッファ)
ADCBUF0 0280 ADC Data Buffer 0 未知
... ... ...
ADCBUFF 029E ADC Data Buffer 15
Table 17-10: ADC Register Map (DS70064E)

ブロック図

10bit A/D


図のようにS/H回路 (Sample Hold) が4つあるため、4つの信号を同時に入力できます。

12bit A/D

初期化

void OpenADC10(
    unsigned int config1,      // ADCON1レジスタ (A/D Control1) の値
    unsigned int config2,      // ADCON2レジスタ (A/D Control2) の値
    unsigned int config3,      // ADCON3レジスタ (A/D Control3) の値
    unsigned int configport,   // ADPCFGレジスタ (A/D Port Configuration) の値
    unsigned int configscan    // ADCSELレジスタ (A/D Input Scan Selection) の値
    )
第1引数config1の定数 (ADCON1)
区分 定数 説明
A/Dコンバータ 有効/無効 ADC_MODULE_ON A/Dコンバータ 有効
ADC_MODULE_OFF A/Dコンバータ 無効
アイドルモード時の動作 ADC_IDLE_CONTINUE A/D Operate in Idle mode
ADC_IDLE_STOP A/D Stop in Idle mode
出力データ書式
Output Formats
ADC_FORMAT_SIGN_FRACT 符号付き小数
ADC_FORMAT_FRACT 小数
ADC_FORMAT_SIGN_INT 符号付き整数
ADC_FORMAT_INTG 整数
変換トリガーソース選択
SSRC:Conversion Trigger Source Select
ADC_CLK_AUTO 内部カウンター (自動変換)
ADC_CLK_MPWM モーター制御PWM (MPWM) インターバル
ADC_CLK_TMR タイマー比較
ADC_CLK_INT0 INT0ピンのアクティブへの変化
ADC_CLK_MANUAL サンプル有効化 (SAMP) ビットのクリア (手動変換)
同時サンプル選択
Simultaneous sampling
ADC_SAMPLE_SIMULTANEOUS 複数チャンネルを同時にサンプリングする
ADC_SAMPLE_INDIVIDUAL 複数チャンネルを順にサンプリングする
自動サンプリング 有効/無効 ADC_AUTO_SAMPLING_ON 自動サンプリング
ADC_AUTO_SAMPLING_OFF 手動サンプリング
サンプリング ADC_SAMP_ON 開始 (サンプリング中)
ADC_SAMP_OFF 停止 (ホールド中)
第2引数config2の定数 (ADCON2)
区分 定数 説明
電圧リファレンス
Voltage reference
ADC_VREF_AVDD_AVSS 下表を参
ADC_VREF_EXT_AVSS
ADC_VREF_AVDD_EXT
ADC_VREF_EXT_EXT
CH0のスキャン 有効/無効 ADC_SCAN_ON A/D Scan Input Selections for CH0 during SAMPLE A
ADC_SCAN_OFF A/D Do notScan Input Selections for CH0+ during SAMPLE A
使用チャンネル ADC_CONVERT_CH_0ABC CH0、CH1、CH2、CH3を変換
ADC_CONVERT_CH_0A CH0、CH1を変換
ADC_CONVERT_CH0 CH0を変換
割り込み頻度 (バッファの使用数) ADC_SAMPLES_PER_INT_n n回のサンプリングと変換の完了ごとに割り込む (nは1~16のいずれか)

ここで設定されたn個まで、バッファ (ADCBUFx) に変換結果が格納される

バッファモード選択 ADC_ALT_BUF_ON 2つの8ワード バッファ
ADC_ALT_BUF_OFF 1つの16ワード バッファ
交互入力サンプルモード ADC_ALT_INPUT_ON MUXAとMUXBを交互に使用する
ADC_ALT_INPUT_OFF MUXAだけを使用する
第3引数config3の定数 (ADCON3)
区分 定数 説明
自動サンプル時間※1 ADC_SAMPLE_TIME_n n Tabの自動サンプル時間 (nは0~31のいずれか)

自動変換の時間として使用される

変換クロック ソース ADC_CONV_CLK_INTERNAL_RC 内部RCクロック
ADC_CONV_CLK_SYSTEM システムクロック
変換クロック ADC_CONV_CLK_nTcy nは、空欄または2~32のいずれか
ADC_CONV_CLK_nTcy2 nは、空欄または3,5,7,…,59,61,63のいずれか
※1 自動サンプリングが無効 (手動) のとき、自動サンプル時間の設定は無視されます。

入出力ピンを、アナログまたはデジタルに指定します。

アナログ入力とするピンは、対応するTRISビットが'1'となり、入力に設定されている必要があります。なお既定では、リセット時には入力に設定されています。

第4引数configportの定数 (ADPCFG)
  説明
ENABLE_ALL_DIG すべてのピンをデジタル モードにする
ENABLE_ALL_ANA すべてのピンをアナログ モードにする
ENABLE_ANn_ANA ANnピンをアナログ モードにする
(nは0~15のいずれか)

自動スキャンに含めるピンを指定します。

第5引数configscanの定数 (ADCSEL)
定数 説明
SCAN_NONE Skip AN0-AN15 for Input Scan
SCAN_ALL Enable AN0-AN15 for Input Scan
SKIP_SCAN_ANn Skip ANn for Input Scan
(nは0~15のいずれか)

出力データ書式 (Output Formats)

バッファへの格納形式
書式 符号ビット データ
符号付き小数
(signed fractional)
最上位ビット 左寄せ
小数
(fractional)
なし 左寄せ
符号付き整数
(signed integer)
最上位ビット 右寄せ
整数
(integer)
なし 右寄せ
各フォーマットのバッファへの格納例
VIN VREF 10bit
出力コード
16bit フォーマット
整数 符号付き整数 小数 符号付き小数
1023 1024 11 1111 1111 0000 0011 1111 1111 0000 0001 1111 1111 1111 1111 1100 0000 0111 1111 1100 0000
  = 1023 = 511 = 0.999 = 0.499
1022 11 1111 1110 0000 0011 1111 1110 0000 0001 1111 1110 1111 1111 1000 0000 0111 1111 1000 0000
  = 1022 = 510 = 0.998 = 0.498
... ...
513 10 0000 0001 0000 0010 0000 0001 0000 0000 0000 0001 1000 0000 0100 0000 0000 0000 0100 0000
  = 513 = 1 = 0.501 = 0.001
512 10 0000 0000 0000 0010 0000 0000 0000 0000 0000 0000 1000 0000 0000 0000 0000 0000 0000 0000
  = 512 = 0 = 0.500 = 0.000
511 01 1111 1111 0000 0001 1111 1111 1111 1111 1111 1111 0111 1111 1100 0000 1111 1111 1100 0000
  = 511 = -1 = 0.499 = -0.001
... ...
1 00 0000 0001 0000 0000 0000 0001 1111 1110 0000 0001 0000 0000 0100 0000 1000 0000 0100 0000
  = 1 = -511 = 0.001 = -0.499
0 00 0000 0000 0000 0000 0000 0000 1111 1110 0000 0000 0000 0000 0000 0000 1000 0000 0000 0000
  = 0 = -512 = 0.000 = -0.500
Figure 17-23: Numerical Equivalents of Various Result Codes (DS70064E)

自動サンプリング

サンプリングのタイミングが重要な場合には「手動」で、さもなくば「自動」を指定します。

手動 (ADC_AUTO_SAMPLING_OFF)

サンプル有効化 (SAMP) ビットを'1'とした後に、サンプリングを開始します。

自動 (ADC_AUTO_SAMPLING_ON)

最後の変換完了後、ただちにサンプリングを開始します。

変換トリガーソース選択 (Conversion Trigger Source Select)

変換トリガーソースは、サンプリングの停止とA/D変換の開始方法を設定します。有効な変換トリガーソースは、デバイスの種類によって異なります。

変換トリガーソースは、A/Dモジュールが無効の状態でなければ変更できません。

手動変換 (ADC_CLK_MANUAL)

SAMPビットを'1'とするとサンプリングを開始し、'0'とするとサンプリングを停止し変換を開始します。サンプリング時間の調整もソフトウェアにより行う必要があります。

自動変換 (ADC_CLK_AUTO)

内部カウンターに基づき、サンプリングの開始と停止を行います。このときサンプリング時間 (TSMP) は、

TSMP = SAMC * TAD

であり、自動サンプル時間 (SAMC) とアナログモジュール クロック (TAD) により決定されます。

電圧リファレンス (Voltage reference)

A/D変換のための電圧リファレンスを設定します。

電圧リファレンスにするピン
定数 Vref+ Vref- 基準
ADC_VREF_AVDD_AVSS AVDD AVSS モジュール電源
ADC_VREF_EXT_AVSS VREF+ AVSS モジュール電源と参照電圧
ADC_VREF_AVDD_EXT AVDD VREF-
ADC_VREF_EXT_EXT VREF+ VREF- 参照電圧

電圧リファレンスに使用するピンは、次の特性を持ちます。

電気特性
分類 記号 説明 電圧範囲※1
下限 [V] 上限 [V]
モジュール電源 AVDD 供給電源 VDD - 0.3 または
2.7の大きい方
VDD + 0.3 または
5.5の小さい方
AVSS グラウンド VSS - 0.3 VSS + 0.3
参照電圧 VREF+ 参照電圧の上限 AVSS + 2.7 AVDD
VREF- 参照電圧の下限 AVSS AVDD - 2.7
※1 dsPIC30F4012の値

自動スキャン (Auto Scan)

あらかじめ指定されたピンを、自動で連続してA/D変換します。その結果はバッファに保存されます。

変換クロック (A/D Conversion Clock)

A/D変換のクロック源には、

  • 内部RCクロック … 変換時間は一定、SLEEPでも有効
  • システムクロック … 変換時間は変更可、SLEEPでは停止

の2種類があります。

アナログモジュール クロック (TAD)

A/D変換のタイミングはアナログモジュール クロック (TAD) により制御され、デバイス命令クロック周期 (TCY) と変換クロック選択ビット (ADCS) により、次式により決定されます。

FCY = オシレータ周波数 * PLLの乗数 / 4

TCY = 1 / FCY

TAD = TCY (ADCS + 1 ) / 2

正常にA/D変換をするためには、TAD167ns以上となるようにクロックを選択する必要があります。

TADの時間
クロックソース デバイス命令クロック周期 (TCY)
/ 命令サイクルクロック (FCY)
クロック ADCS 50ns
/ 20MHz
100ns
/ 10MHz
1000ns
/ 1MHz
TCY2 00 0000 ※1 25ns ※1 50ns 500ns
TCY 00 0001 ※1 50ns ※1 100ns 1000ns
3TCY2 00 0010      
2TCY 00 0011 ※1 100ns 200ns 2000ns
5TCY2 00 0100      
3TCY 00 0101 ※1 150ns 400ns 3000ns
7TCY2 00 0110      
4TCY 00 0111 200ns 400ns 4000ns
RC※2 xx xxxx 200 - 400ns
※1 TADの最低値 167nsを下回るため、無効な値となります。
※2 内部RCクロックは、変換クロック選択ビットの影響を受けません。

A/D変換には12クロック周期が必要なため、変換にかかる時間はTADの12倍となります。

A/D変換の実行

A/D変換は、次の手順で行います。

  1. チャンネルを指定する (SetChanADC10)
  2. サンプリングを開始する (※自動サンプリングが無効の場合のみ)
  3. A/D変換を開始する (ConvertADC10) (※手動変換の場合のみ)
  4. 変換終了まで待機する (BusyADC10)
  5. 変換結果を読み込む (ReadADC10)

手順2のサンプリング開始では、サンプルホールド回路 (S/H回路) へのアナログ入力のチャージを開始します。そして手順3でそれのA/D変換を開始し、変換結果をバッファに格納します。

サンプリングとA/D変換は別の工程です。

1. チャンネルの指定

A/D変換を行うには、どのA/Dコンバータから入力をするのか、まずそのチャンネルを指定する必要があります。

void SetChanADC10( unsigned int channel )

引数のchannelに指定できる値は、次の定数のいずれかです。

  チャンネル数 Mux A※1 Mux B
正側 単一 ADC_CH0_POS_SAMPLEA_AN0 ADC_CH0_POS_SAMPLEB_AN0
ADC_CH0_POS_SAMPLEA_AN1 ADC_CH0_POS_SAMPLEB_AN1
ADC_CH0_POS_SAMPLEA_AN15 ADC_CH0_POS_SAMPLEB_AN15
複数 ADC_CHX_POS_SAMPLEA_AN0AN1AN2 ADC_CHX_POS_SAMPLEB_AN0AN1AN2
ADC_CHX_POS_SAMPLEA_AN3AN4AN5 ADC_CHX_POS_SAMPLEB_AN3AN4AN5
負側 単一 ADC_CH0_NEG_SAMPLEA_NVREF ADC_CH0_NEG_SAMPLEB_NVREF
ADC_CH0_NEG_SAMPLEA_AN1 ADC_CH0_NEG_SAMPLEB_AN1
複数 ADC_CHX_NEG_SAMPLEA_NVREF ADC_CHX_NEG_SAMPLEB_NVREF
ADC_CHX_NEG_SAMPLEA_AN6AN7AN8 ADC_CHX_NEG_SAMPLEB_AN6AN7AN8
ADC_CHX_NEG_SAMPLEA_AN9AN10AN11 ADC_CHX_NEG_SAMPLEB_AN9AN10AN11
※1 Mux = Multiplexer (マルチプレクサ)

正入力と負入力を対応するように設定します。

SetChanADC10(
    ADC_CH0_POS_SAMPLEA_AN0 &
    ADC_CH0_NEG_SAMPLEA_NVREF );

アナログ入力マルチプレクサは、MUXAとMUXBの2つの入力設定構成をサポートしており、A/D変換の合間に構成を切り替えて使用できます。

2. サンプリングの開始

この処理は、自動サンプリングが無効とされている場合のみ有効です。

サンプル有効化 (SAMP) ビットを'1'とします。

ADCON1bits.SAMP = 1;

3. 変換の開始

この処理は、変換トリガーソース選択で手動変換が選択されている場合のみ有効です。

A/Dコンバータのサンプリングを停止し、変換の開始を指示します。これは「ADCON1bits.SAMP = 0」とするのと同義です。

void ConvertADC10( void )

または、

#define StopSampADC10 ConvertADC10

のように定義されているため、StopSampADC10()でも同様です。

4. 変換完了の待機

A/D変換が完了するのを待ちます。変換の完了はADCON1<DONE>で確認でき、関数ではBusyADC10()を用います。

char BusyADC10( void )

ただ、この関数はADCON1<DONE>とは逆の値を返すことに注意が必要です。

ADCON1<DONE>とBusyADC10()の戻り値
  A/D変換中 A/D変換完了
ADCON1<DONE> 0 1
BusyADC10() 1 0

単純に変換完了を待つだけならば、次のようにします。

while( BusyADC10() );

または、

while( ! ADCON1bits.DONE );

としても同様です。ただしこの方法ではループを抜けられなくなる恐れがあるため、後述の割り込みを使用します。

変換時間の算出

 

5. 変換結果の読み込み

バッファのインデックスを指定して、バッファから変換結果を読み込みます。

unsigned int ReadADC10( unsigned char bufIndex )

SMPI (ADCON2<5:2>) で設定される割り込み頻度が1のとき、変換結果はつねにインデックス0のバッファに書き込まれます。

割り込み (Interrupt)

A/D変換の完了で割り込みが発生します。

許可、禁止

/* Macros to Enable/Disable interrupts of ADC module */
#define EnableIntADC     IEC0bits.ADIE = 1
#define DisableIntADC    IEC0bits.ADIE = 0

割り込み優先順位

#define SetPriorityIntADC( priority )    IPC2bits.ADIP = ( priority )

設定

ConfigIntADC10()で、割り込みの許可、禁止および割り込み優先順位を一括して設定できます。

void ConfigIntADC10( unsigned int config )
/* Setting the priority of adc interrupt */
#define ADC_INT_PRI_0                   0xFFF8
#define ADC_INT_PRI_1                   0xFFF9
#define ADC_INT_PRI_2                   0xFFFA
#define ADC_INT_PRI_3                   0xFFFB
#define ADC_INT_PRI_4                   0xFFFC
#define ADC_INT_PRI_5                   0xFFFD
#define ADC_INT_PRI_6                   0xFFFE
#define ADC_INT_PRI_7                   0xFFFF

/* enable / disable interrupts */
#define ADC_INT_ENABLE                  0xFFFF
#define ADC_INT_DISABLE                 0xFFF7

参考

  • Section 17. 10-bit A/D Converter (DS70064E)
  • dsPIC30Fファミリー リファレンスマニュアル (DS70046B_JP)
    17章「10ビットA/D コンバータ」
  • dsPIC30F ADC10 Peripheral Module Library Help/Microchip/MPLAB C30/docs/periph_lib/dsPIC30F_ADC10_Library_Help.htm