目次8章.機能が豊富なPICを使う(PIC12F683)>(9)A/D変換を使う

A/D変換を使う (PIC12F683)
更新日2006.10.14

PIC12F683のA/D変換を使ってみます。
A/D変換の入力は可変抵抗(ボリューム)にしました。PWM機能を使ってスピーカを鳴らすで行ったようにスピーカを出力にして、音の高さをボリュームで変化させます。

実験回路
「スピーカを鳴らす」で使った回路にボリュームを追加します。ボリュームは下図のようにGP4(AN3)に接続します。

ブレッドボードに組み込んだ状態
GP2ピン側の10KΩの抵抗は省略しました。

プログラムの仕様
GP4(AN3)に接続したボリュームでGP4(AN3)の電圧を変化させます。その電圧をA/D変換してPICに取り込みます。
A/D変換で取り込んだ値をPWMの周期として、GP2(CCP1)に接続したスピーカを鳴らします。
結果的に、ボリュームを回すことで音の高さが変わります。


以下では、A/D変換について説明します。
PWMについては、PWM機能を使ってスピーカを鳴らすを参照して下さい。

A/D変換について
A/D変換とは、アナログ信号(電圧)をデジタルデータに変換することです。
PIC12F683では、アナログポート(AN0〜AN3)の電圧を10ビットの数値に変換します。
変換は、基準電圧を1024として測定電圧を表現します。

ADres=Vin/(Vref/1024)

ただし、ADresの最大値は1023です。(16進表現で、'3FF'まで)

例えば、基準電圧が5Vで測定電圧が2.5Vの場合、AD変換の結果(ADres)は512になります。

ADres=Vin/(Vref/1024)
=2.5/(5/1024)
=512

A/D変換の手順

A/D変換を行う手順は以下の通りです。

(1)A/D変換機能の初期設定
以下の3つのレジスタ設定を行います。
ANSELA/D変換のクロック設定と、A/D変換の入力ピンを指定
TRISIOA/D変換の入力ピンを入力モードに設定
ADCON0基準電圧の選択,A/D変換結果の格納方法指定,A/D変換の入力ピン選択を行い、A/D変換を有効に設定

(2)A/D変換準備完了を待つ
PIC内蔵のコンデンサ充電完了を待ちます。
この時間をアクィジション時間と言い、入力抵抗が10KΩの時、約20μ秒です。

(3)A/D変換を開始する
ADCON0レジスタのGOビットをONにしてA/D変換を開始します。

(4)A/D変換完了を待つ
ADCON0レジスタのGOビットがOFF(A/D変換完了)になるのを待ちます。

(5)A/D変換結果を使う
A/D変換結果が、ADRESH,ADRESLレジスタに格納されていますので、目的に応じて使用します。

(6)繰り返す
繰り返す場合は、(2)に戻ります。

【参考】
A/D変換完了を待つ方法として、上ではADCON0レジスタのGOビットがOFFになるのを待っていますが、A/D変換完了割込みを使う方法もあります。
A/D変換完了割込みを使う場合、以下のレジスタ操作が必要です。
INTCON,PIR1,PIE1


基準電圧

基準電圧は、以下のいずれかを選択します。

・電源電圧Vdd
・GP1/Vref(6番ピンに与える電圧)
どちらにするかは、ADCON0レジスタのVCFGビットで設定します。

今回は、精度は要求されませんので、電源電圧を基準電圧にしました。

入力ポートの選択

A/D変換で使えるポートは、AN0〜AN3の4ポートがあります。1つだけをA/D変換で使い、他はデジタルI/Oにすることもできますし、4つ共A/D変換で使うこともできます。
この選択は、ANSELレジスタのANS0〜ANS3で指定します。

ただし、1回のA/D変換動作では、1つのポートだけを対象とする必要があり、このポート選択は、ADCON0レジスタのCHS0,CHS1で設定します。

A/D変換のクロック選択(TAD)

A/D変換のクロックは、下の表の水色の範囲を指定します。
PICを動作させるオシレータ(クロック)の周波数と、ANSELレジスタのADCS2〜0の設定値で決定します。
今回は、オシレータを4MHzにしましたので、8Toscを選択し2.0μ秒にしました。

A/Dクロック設定オシレータ周波数
動作ADCS2-020MHz5MHz4MHz1.25MHz
2Tosc000100nS400nS500nS1.6μS
4Tosc100200nS800nS1.0μS3.2μS
8Tosc001400nS1.6μS2.0μS6.4μS
16Tosc101800nS3.2μS4.0μS12.8μS
32Tosc0101.6μS6.4μS8.0μS25.6μS
64Tosc1103.2μS12.8μS16.0μS51.2μS
A/D RCx112-6μS2-6μS2-6μS2-6μS
表の水色の範囲を使用します。
A/D変換のクロックは、最低が1.6μSですので、表の青の部分は使用できません。
また、赤の部分は変換時間が長くなるためお勧めできませんとのことです。
【ToscとFosc】
Toscはオシレータの1クロック(1サイクル)の時間であり、8Toscは1クロックの時間の8倍という意味です。
Foscはオシレータの周波数で、Fosc/8はオシレータの周波数の1/8という意味です。


A/D変換結果の格納

A/D変換結果は10ビットです。一方、PICのレジスタは8ビットです。
そのままでは格納できませんので、ADRESHレジスタとADRESLレジスタの2つを連結した16ビットに格納されます。
16ビット幅に10ビットを格納しますが、以下の2パターンから選択できます。
 ・左詰めで下位の6ビットを0にする
 ・右詰めで上位の6ビットを0にする
この選択は、ADCON0レジスタのADFMビットで指定します。

今回は左詰めとし、ADRESHレジスタだけを使いました。

プログラム全体
プログラムはこちらです。
メモ帳などのテキストエディタに取り込んで、P683AD.ASMという名で保存し、MPLABでアセンブル&PICライタでPICに書き込んで動かしてみて下さい。

今まで、PIC16F84Aを使用していた場合は、MPLABのプロジェクトウィザードで「PIC12F683」を選択して下さい。
また、PICライタでも同様に「PIC12F683」を選択して下さい。

ボリュームを回して音の高さが変化すれば成功です。

簡単な追加実験

追加実験 その1(LEDを0.5秒毎に点滅)
上のソースプログラムの136行目と137行目がコメントアウトしてありますが、コメントを外して(行の先頭のセミコロン(;)を削除して)実行してみて下さい。
PICの2番ピン(GP5)に接続してあるLEDが点滅すると思います。
ですが、音にノイズが乗りませんか?

PWMの周期の切れ目をプログラムで判断できればノイズを消せますが、本来の使い方では無いので無理なようです。

PWMの機能
本来・・周期は固定でパルス幅を変える(パルス幅の変更は周期の切れ目で反映される)
今回・・周期とパルス幅を変える

追加実験 その2(明るさで音の高さを変える)
Cdsセルを使ってみましょう。
10KΩの可変抵抗とグランド(電源のマイナス側)間にCdsセルを接続して下さい。
明るさの変化で音の高さが変わりましたか?