このページでは、おもに10bitのA/Dについて取り上げます。12bitとは異なる点があることに注意してください。
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 | ? |
ライブラリファイルは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の割り込みを設定する |
マクロ | 説明 |
---|---|
EnableIntADC | |
DisableIntADC | |
SetPriorityIntADC |
区分 | 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 |
図のようにS/H回路 (Sample Hold) が4つあるため、4つの信号を同時に入力できます。
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) の値 )
区分 | 定数 | 説明 |
---|---|---|
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 | 停止 (ホールド中) |
区分 | 定数 | 説明 |
---|---|---|
電圧リファレンス 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だけを使用する |
区分 | 定数 | 説明 |
---|---|---|
自動サンプル時間※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のいずれか |
入出力ピンを、アナログまたはデジタルに指定します。
アナログ入力とするピンは、対応するTRISビットが'1'となり、入力に設定されている必要があります。なお既定では、リセット時には入力に設定されています。
説明 | |
---|---|
ENABLE_ALL_DIG | すべてのピンをデジタル モードにする |
ENABLE_ALL_ANA | すべてのピンをアナログ モードにする |
ENABLE_ANn_ANA | ANnピンをアナログ モードにする (nは0~15のいずれか) |
自動スキャンに含めるピンを指定します。
定数 | 説明 |
---|---|
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のいずれか) |
書式 | 符号ビット | データ |
---|---|---|
符号付き小数 (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 |
サンプリングのタイミングが重要な場合には「手動」で、さもなくば「自動」を指定します。
サンプル有効化 (SAMP) ビットを'1'とした後に、サンプリングを開始します。
最後の変換完了後、ただちにサンプリングを開始します。
変換トリガーソースは、サンプリングの停止とA/D変換の開始方法を設定します。有効な変換トリガーソースは、デバイスの種類によって異なります。
変換トリガーソースは、A/Dモジュールが無効の状態でなければ変更できません。
SAMPビットを'1'とするとサンプリングを開始し、'0'とするとサンプリングを停止し変換を開始します。サンプリング時間の調整もソフトウェアにより行う必要があります。
内部カウンターに基づき、サンプリングの開始と停止を行います。このときサンプリング時間 (TSMP) は、
TSMP = SAMC * TAD
であり、自動サンプル時間 (SAMC) とアナログモジュール クロック (TAD) により決定されます。
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 |
あらかじめ指定されたピンを、自動で連続してA/D変換します。その結果はバッファに保存されます。
A/D変換のクロック源には、
の2種類があります。
A/D変換のタイミングはアナログモジュール クロック (TAD) により制御され、デバイス命令クロック周期 (TCY) と変換クロック選択ビット (ADCS) により、次式により決定されます。
FCY = オシレータ周波数 * PLLの乗数 / 4
TCY = 1 / FCY
TAD = TCY (ADCS + 1 ) / 2
正常にA/D変換をするためには、TADが167ns以上となるようにクロックを選択する必要があります。
クロックソース | デバイス命令クロック周期 (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 |
A/D変換には12クロック周期が必要なため、変換にかかる時間はTADの12倍となります。
A/D変換は、次の手順で行います。
手順2のサンプリング開始では、サンプルホールド回路 (S/H回路) へのアナログ入力のチャージを開始します。そして手順3でそれのA/D変換を開始し、変換結果をバッファに格納します。
サンプリングとA/D変換は別の工程です。
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 |
正入力と負入力を対応するように設定します。
SetChanADC10( ADC_CH0_POS_SAMPLEA_AN0 & ADC_CH0_NEG_SAMPLEA_NVREF );
アナログ入力マルチプレクサは、MUXAとMUXBの2つの入力設定構成をサポートしており、A/D変換の合間に構成を切り替えて使用できます。
この処理は、自動サンプリングが無効とされている場合のみ有効です。
サンプル有効化 (SAMP) ビットを'1'とします。
ADCON1bits.SAMP = 1;
この処理は、変換トリガーソース選択で手動変換が選択されている場合のみ有効です。
A/Dコンバータのサンプリングを停止し、変換の開始を指示します。これは「ADCON1bits.SAMP = 0
」とするのと同義です。
void ConvertADC10( void )
または、
#define StopSampADC10 ConvertADC10
のように定義されているため、StopSampADC10()でも同様です。
A/D変換が完了するのを待ちます。変換の完了はADCON1<DONE>で確認でき、関数ではBusyADC10()を用います。
char BusyADC10( void )
ただ、この関数はADCON1<DONE>とは逆の値を返すことに注意が必要です。
A/D変換中 | A/D変換完了 | |
---|---|---|
ADCON1<DONE> | 0 | 1 |
BusyADC10() | 1 | 0 |
単純に変換完了を待つだけならば、次のようにします。
while( BusyADC10() );
または、
while( ! ADCON1bits.DONE );
としても同様です。ただしこの方法ではループを抜けられなくなる恐れがあるため、後述の割り込みを使用します。
バッファのインデックスを指定して、バッファから変換結果を読み込みます。
unsigned int ReadADC10( unsigned char bufIndex )
SMPI (ADCON2<5:2>) で設定される割り込み頻度が1のとき、変換結果はつねにインデックス0のバッファに書き込まれます。
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