2016-05-30 20:00 | カテゴリ:PIC応用回路
前回ご紹介しましたPICのAD変換によるサーボの制御について、AD変換の設定方法と使用方法について、少し御説明したいと思います。
以下の説明は、PIC-16F87Xが前提になっていますので、他のPICでは設定の方法などが異なるかもしれません。

16F87Xには、RA0-5のポートのうち、RA4を除いて5つのポートをAD変換の入力に割り当てることが出来ます。
それぞれ、AN0-AN4の4つのchに割り当てられます。(下図参照)
実際のAD変換を行う回路は1ch分しか内蔵されていませんので、どのchのアナログ信号をAD変換するのかを指定し、それを切り替えすることによって、5chのAD変換を実現しています。

(注:出展はマイクロチップ社 データシートです)

PIC.jpg

続きへ、、、、

AD変換を設定、制御するレジスターがいくつかあります。
まず、各レジスターの機能を説明します。

一つ目は、ADCON0レジスターです。

ADCON0.jpg

まず、
Bit7-6は、AD変換する際のクロックの指定です。
PICは接続されるクリスタルやセラロックにより動作周波数が異なりますので、AD変換に供給される周波数を指定します。
PICのクロックの周波数が5-20MHzの場合は、ここをBit7=1、Bit6=0にします。

AD_Clock.jpg
Bit3-5は、どのポートに接続された信号をAD変換するのかを指定します。

Bit2は、D変換の開始の指示と、AD変換が完了したことのフラグをかねています。
Bit1は未使用。
Bit0は、AD変換回路のON/OFF切り替えになります。


次が、ADCON1レジスターです。

ADCON1.jpg

Bit7は、AD変換結果(10ビット分)を指定レジスタ(16ビット)に右詰めで格納するか左詰めで格納するかを指定します。
Bit0-3は、AD変換にどのポートを使用し、どのポートを通常のI/Oポートとして使用するのかの組み合わせを指定します。
また、AD変換の際の基準電圧は、0V-VDD(電源電圧)ですが、特定のI/Oポートに基準電圧を別途設定して、それを基準としてAD変換することも出来ます。

AD変換の結果の取り出し方ですが、ADRESHとADRESLという二つのレジスタに結果がセットされますので、そのレジスタを読み出せばえられます。

AD_Result.jpg

AD変換の結果は10ビットです。この10ビットを、8+8=16ビットのレジスタに、右詰めでセットするか左詰めでセットするかの指示が、先ほどのADCON1のレジスタのBit7でできます。
10ビットフルで結果を得たい場合は右詰め(ADFM=1)にして、ADRESHとADRESLの二つのレジスタを読みます。
結果が上位8ビットでよい場合(扱いやすい)は、左詰め(ADFM=0)にして、ADRESHだけを読み出せばよいことになります。(結果は0から255です)


では、具体的な手順を示します。一例です。
今回のAN0のADチャンネルの変換で、ADの結果を8ビットで得る手順になります。


//---------------------------------------------
// PICのPORT設定の初期化 AD変換RA0ポートに設定
//---------------------------------------------
//PICのポート設定

TRISA = 0b00000001; // A/D変換はRA0で行うのでRA0を入力に設定

ADCON0 = 0b10000001; //アナログ使用AD0のみ、あとは全てデジタルとする設定。
 Bit7-6=10として、AD変換クロックの指定。
 Bit3-5=000でAN0のポートを指定。(今回は1つのポートだけなので、ここは変更しません)
 Bit2-1=0のままです。
 Bit0=1として、AD回路をONにします。

ADCON1 = 0b00001110; //
 Bit7=0で結果を左寄せで格納
 Bit3-0=1110でRA0ポートのみADとして使用し、残りはデジタルポートとして設定

ここまでで、準備は出来ました。

AD変換の実行は、



//-------------------------------------------------------------------
// RA0のchでAD変換を実行し結果をservoに代入する
// AD変換結果は0-256となるので、250以上は250として処理
//-------------------------------------------------------------------

void ad_conv(void) {
ADCON0 = 0b10000001; // AD変換準備RA0チャンネルを指定します。もし複数のADチャンネルを使用する場合はここでそのChを指定します。
  // 今回はADは一つだけなので、ここで指定しなくても大丈夫です。

__delay_us(20); // 20usecの準備待ち。ADにチャージされるまで最低20マイクロ秒以上待ちます。

GO = 1; // AD変換開始。ADCON0レジスタのBit2はGOという変数で内部定義されています。これを1にするとAD変換が開始されます。

while (GO) {
// GOビットが1の間待つ(0になるまで待つ)
 // GOびっとが0になるとAD変換が完了した合図です。
}
servo = ADRESH;//AD変換完了後、結果を読みに行きます。今回は結果は左寄せで、8ビットです。

}


以上、ここのad_conv()関数を繰り返して実行すればその都度、AD変換が実行されて、値がADRESHに格納されます。


大体、この様な感じでAD変換を実行できます。
是非、応用してみてください。

御参考になれば幸いです。

管理者のみに表示する