PIC12F683でA/D変換を使う方法をまとめました。今回紹介するのは、シンプルにするために、割込みを使わないやり方です。
A/D変換を使うための8ステップ
PIC12F683でA/D変換は、こんな流れで実行します。
- ピンをアナログ入力に設定する
- A/D変換モジュールの設定をする
- A/D変換モジュールを有効にする
- チャンネル設定をする
- 20μsくらい待つ
- A/D変換をスタートさせる(A/D変換開始)
- 変換完了まで待つ
- 変換結果のデータを読み出す
Step1:ピンをアナログ入力に設定する
まず、「TRISIOレジスタ」でピンを入力に設定します。
A/D変換に設定したいピンに対応するビットを「1」にします。(TRISIOの後ろに続く数字は、ピンのGPの数字に対応している)
次に、「ANSELレジスタ」のANS<3:0>でピンをアナログ入力に設定します。
A/D変換に設定したいピンに対応するビットを「1」にします。(ANSの後ろに続く数字は、ピンのANの数字に対応している)
Step2:A/D変換モジュールの設定をする
A/D変換モジュール用クロックの設定
A/D変換モジュール用のクロックは、「ANSELレジスタ」のADCS<2:0>で設定します。
A/D変換用のクロックは、その逆数Tadが3us~9usくらいになるように選びます。どの設定にしても、この範囲(3us~9us)に入らない場合は、A/D変換モジュール専用クロックFrcを使う設定(ADCS=x11)にします。
基準電圧の選択
A/D変換のフルスケール(最大値)に対応する電圧を、どの電圧にするかを選択できます。「ADCON0レジスタ」のVCFGが"0"の場合、電源電圧(Vdd)がA/D変換の最大値となるようにA/D変換されます。そのため、A/D入力ピンの電圧がVdd/2のときには、変換された値は「512」になります。VCFGを"1"にすると、Vrefピンの電圧が、A/D変換の最大値となるようにA/D変換されます。
変換結果の「右詰め/左詰め」を選択
「ADCON0レジスタ」のADFMで、A/D変換した結果(10bit)を、右詰めとするか、左詰めとするかを選択します。
A/D変換した結果のデータは、「ADRESH」、「ADRESL」の2つのレジスタに分けて格納されます。「ADRESH」と「ADRESL」はそれぞれ8bitなので、10bitのデータが2bitと8bitに分けて格納されます。
「右詰め」とすると、上位バイトである「ADRESH」に2bit、下位バイトの「ADRESL」に8bit格納されます。
A/D変換を10bitで行いたい(変換したデータを10bitで取り扱いたい)ときは、データの取扱がラクなので、右詰めがおすすめです。
A/D変換結果を8bitで取り扱う場合(8bit分解能で構わないとき)は、データを左詰めとするのがおすすめです。
データを左詰めとして、下位2bitを無視し、上位バイトのみ使用すると、8bit分解能となります。データの結合処理がいらなくなり、処理が軽くなります。
Step3:A/D変換モジュールを有効にする
「ADCON0レジスタ」のADONを"1"として、A/D変換モジュールを有効化します。
Step4:チャンネル設定をする
「ADCON0レジスタ」のCHS<1:0>で、内蔵A/D変換器に接続するピンを設定します。
PIC12F683の内蔵A/D変換器はひとつで、一度にA/D変換できるのは、ひとつだけです。複数のアナログ入力ピンを使用する場合は、チャンネルを切り替えて、順次A/D変換を実行していくことになります。
Step5:20μsくらい待つ
A/D変換器のサンプルホールド用コンデンサの充電時間として、20μs程度待ちます。
xc.hに__delay_us()というビルトイン関数があるので、これを使うと便利です。
Step6:AD変換をスタートさせる(AD変換開始)
「ADCON0」のGO/DONEを"1"とすると、A/D変換が開始されます。
Step7:変換完了まで待つ
A/D変換が完了すると、「ADCON0」のGO/DONEが"0"となるので、このビットが"0"になるまで待ちます。
Step8:変換結果のデータを読み出す
A/D変換結果は、「ADRESH」と「ADRESL」レジスタに格納されているので、値を読み出します。
A/D変換プログラムの例
この例では、こんな設定で書いています。
- 3ピン(GP4、AN3)をアナログ入力として使う
- A/DクロックはFrc
- 基準電圧はVdd
- データは右詰め(10bitデータとして扱う)
レジスタは1バイトまとめて書く方が多いと思いますが、ここでは上記のStepに合わせて、ひとつずつ(項目ごとに)設定しています。
また、このコードは、A/D変換に直接関係ない部分は省いています。(コンフィグ設定など)
#include <xc.h> void main( void ){ unsigned short data; // A/D変換結果用 //Step1 TRISIObits.TRISIO4 = 1; // GP4をinputにする ANSELbits.ANS3 = 1; // AN3をアナログ入力にする //Step2 ANSELbits.ADCS = 0x03; // A/D変換クロックはFrc ADCON0bits.VCFG = 0; // 基準電圧はVdd ADCON0bits.ADFM = 1; // データは右詰め //Step3 ADCON0bits.ADON = 1; //ADC有効 //Mainloop while(1){ //Step4 ADCON0bits.CHS = 0x03; // チャンネルセット:AN3 //Step5 __delay_us(20); //wait 20us //Step6 ADCON0bits.GO = 1; //ADC start //Step7 while(ADCON0bits.GO){ // AD変換完了まで待つ } //Step8 data = (ADRESH << 8) & ADRESL; // AD変換結果を読み出し(10bitデータ) } }
0 件のコメント:
コメントを投稿