(2002/8/8)
【A/D変換の使い方】
PIC16F87xシリーズのA/D変換モジュールの内部構成は下図のように
なっていて、右側の入力ピンのいずれか一つが選択されると、
チャネルスイッチの1つがOnとなりサンプルホールドコンデンサに
接続され充電が開始されます。
コンデンサへの充電を待った後、A/D Converterの動作を開始させると
実際に変換を実行し結果がレジスタに保存されます。
また変換動作の基準値を決めるために正負のVref電圧を加えることも
出来ます。このVrefを使わないときには、Vref電圧は0Vと電源電圧(5V)
になります。
さらに、このVrefは2.5V以上でないと10ビット精度は保証されません
ので注意が必要です。
【A/D変換に必要な変換時間】
PICでは、A/D変換をするために、まずアナログ信号を一旦内部のコンデンサ
に蓄えます。その後、参照となる一定の電圧を加算して比較しながら計測する
という原理であるため、A/D変換を正確に行うためには、蓄積するまでの時間
と計測する時間の両方を確保することが必要になります。
従来のPICの場合と比較して、この時間がどれぐらいかというと
蓄積時間+計測時間=
(従来8ビット)
12μsec+1.6μsec×9.5 =最小28μsec
(今回10ビット)
20μsec+1.6μsec×12 =最小39μsec
となります。(クロック20MHzの時)
【レジスタの詳細内容】
A/D変換制御用には3種類のレジスタがありますが、詳細内容と設定内容
は下図の様になっています。
PIC16F87xの種類によってチャンネル数が異なりますが、下図はPIC16F877
の例です。
A/D変換クロック(Tad)の設定方法は下表とします。
上表のようにクロック周波数により可能な設定は黄色の設定
設定
ADCS1,0
PICのクロック周波数
20MHz
10MHz
4MHZ
1MHz
Fosc/2
00
2.0
Fosc/8
01
2.0
8.0
Fosc/32
10
1.6
3.2
8.0
Frc
11
2〜 6
のみとなります。他の設定にした場合には、精度が保証されません。
なぜならA/D用クロックとしては1.6μsec以上必要な為です。
ここでは特にADFMビットの使い方がこれまで無かったものになり、下図の
ような指定になります。
アナログ入力ポートの使い方の設定は下表のようになります
Aはアナログ入力 Dはディジタル入出力 Vref+ Vref-は基準電圧入力
PCFG3−0
RE2
RE1
RE0
RA5
RA3
RA2
RA1
RA0
0000
A
A
A
A
A
A
A
A
0001
A
A
A
A
Vref+
A
A
A
0010
D
D
D
A
A
A
A
A
0011
D
D
D
A
Vref+
A
A
A
0100
D
D
D
D
A
D
A
A
0101
D
D
D
D
Vref+
D
A
A
011x
D
D
D
D
D
D
D
D
1000
A
A
A
A
Vref+
Vref-
A
A
1001
D
D
A
A
A
A
A
A
1010
D
D
A
A
Vref+
A
A
A
1011
D
D
A
A
Vref+
Vref-
A
A
1100
D
D
D
A
Vref+
Vref-
A
A
1101
D
D
D
D
Vref+
Vref-
A
A
1110
D
D
D
D
D
D
D
A
1111
D
D
D
D
Vref+
Vref-
D
A
基準電圧入力の指定が無いときは、電源電圧が基準となる。
【Cコンパイラの組み込み関数】
CCS C Compiler では、A/D変換についても組込み関数が用意されており、
これを使うことで簡単にA/D変換機能を使うことができます。
しかし、A/D変換機能については、PICの種類毎に内容が異なるため、
詳しくはPICのマニュアル、標準インクルードファイルで確認することが必要です。
《A/D変換用組み込み関数》
関数
機能内容
setup_adc(mode) A/D変換のon/offとクロックの指定
modeには下記がある。
ADC_OFF (A/Dをoffにすると消費電流が削減できる)
ADC_CLOCK_DIV_2(CLOCKの1/2)
ADC_CLOCK_DIV_8(CLOCKの1/8)
ADC_CLOCK_DIV_32(CLOCKの1/32)
ADC_CLOCK_INTERNAL(内部RCのクロック)
《例》setup_adc(ADC_CLOCK_INTERNAL);
setup_adc(ADC_CLOCK_DIV_32);
A/D変換用クロックの設定方法
10MHz以上の時には1/32を指定setup_adc_ports(value) A/D変換用の各ピン毎にアナログかディジタルかの
使い方の設定をする。
valueには下記がある。
(RExがあるのはPIC16F874/877に限定される。)
0x80 ALL_ANALOG
0x81 ANALOG_RA3_REF
0x82 A_ANALOG
0x83 A_ANALOG_RA3_REF
0x84 RA0_RA1_RA3_ANALOG
0x85 RA0_RA1_ANALOG_RA3_REF
0X86 NO_ANALOGS
0x88 ANALOG_RA3_RA2_REF
0x89 ANALOG_NOT_RE1_RE2
0x8A ANALOG_NOT_RE1_RE2_REF_RA3
0x8B ANALOG_NOT_RE1_RE2_REF_RA3_RA2
0X8C A_ANALOG_RA3_RA2_REF
0X8D RA0_RA1_ANALOG_RA3_RA2_REF
0X8E RA0_ANALOG
0X8F RA0_ANALOG_RA3_RA2_REF
《例》setup_adc_ports(RA0_RA1_RA3_ANALOG);
setup_adc_ports(ALL_ANALOG);
A/D変換用ピンの使い方set_adc_channel(chan) 読み込むアナログのチャンネル番号(ピン指定)を指定する。
このチャンネル指定後、A/Dクロック×10+15 μsec以上
待ってから読み込むこと。
chanは 0-7 まであるがPICのデバイスにより異なるので注意
《例》set_adc_channel(1);i=read_adc() 直前で指定されたチャンネルからアナログデータを読み込む。8ビットか10ビットかは、#device ADC=8または10で
指定した内容による。
value = read_adc();
【プログラム例】
実際の例で、PIC16F876を使った計測表示で、2チャンネルのアナログ入力を
計測して液晶表示器に表示する例です。
一つは電圧計測、もう一つは温度計測となっています。下記リストがこの例題のリストです。 電圧計測はフルスケールが0.5Vの
10ビット分解能で、少数点以下3桁を表示します。
温度表示は、0℃から50℃のスケールとして0.1℃の分解能で表示しています。
いずれも計測した10ビットのデータを浮動小数点数として扱ってスケール変換の
演算をしています。