PIC16F18346の基本動作から応用プログラムまでを学びます。

ホーム
12F1822
16F1455
16F1459
18F14K50
18F26J50
dsPIC
その他
    
16F18313
16F18325
16F18346
16F1619
Curiosity
---
---
AD変換
2020-09-02

P16F18346には、10ビットのADコンバータ(ADC)が組み込まれています。 pin4(RA3)を除く全てのI/Oピンが外部入力に指定できます。さらに、IC内部で発生させる基準電圧(FVR)とDAコンバータ出力、内部温度を切り替えてAD変換することができます。

AD変換手順
  1. 使用するアナログ入力ピンの設定:
    • 該当するTRIS レジスタのビットを入力「1」に設定
    • 該当するANSEL レジスタのビットを「1」に設定
  2. ADC moduleの設定:
    • AD変換クロックを指定
    • 基準電圧を指定
    • ADC 入力チャネルを指定
    • 結果出力のフォーマットを指定
    • チャージ時間の指定
    • ADC moduleをON
  3. 必要とするチャージ時間を待つ
  4. GO/DONE bitをセットして変換を開始
  5. 変換の終了を以下の方法で待つ:
    • GO/DONE bitを常時監視
    • ADC からのinterrupt を待つ(interrupts使用時)
    • AD変換の結果を取得
    • ADC interrupt flagをクリア (interrupts使用時)
  6. AD変換の結果を取得

充電時間(Acquisition time)

AD変換は、CHS信号により入力電圧を選び、その電圧をモジュール内のコンデンサに充電したのちに開始されます。この充電時間(Acquisition time)を十分にとらないと正確な変換ができません。必要時間は、Vddと入力信号のインピーダンス(Rs)で決まります。
Vdd = 5v、Rs = 10KΩの場合、Acquisition time > 7.37uS の時間が必要です。

レジスタ bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0
TRISA - - TRISA5 TRISA4 - TRISA2 TRISA1 TRISA0
TRISC - - TRISC5 TRISC4 TRISC3 TRISC2 TRISC1 TRISC0
ANSELA - - ANSA5 ANSA4 - ANSA3 ANSA1 ANSA0
ANSELC - - ANSC5 ANSC4 ANSC3 ANSC2 ANSC1 ANSC0
INTCON GIE PEIE - - - - - INTEDG
PIE1 TMR1GIE ADIE RCIE TXIE SSP1IE BCL1IE TMR2IE TMR1IE
PIR1 TMR1GIF ADIF RCIF TXIF SSP1IF BCL1IF TMR2IF TMR1IF
ADCON0 CHS<5:0> GO/DONE ADON
ADCON1 ADFM ADCS<2:0> - ADNREF ADPREF<1:0>
ADACT - - - ADACT<4:0>
FVRCON FVREN FVRRDY TSEN TSRNG CDAFVR<1:0> ADFVR<1:0>
ADRESH A/D Result Register High
ADRESL A/D Result Register Low
レジスタ BIT 内容 1 0
INTCON 7 GIE 全インタラプトの使用許可 許可
6 PEIE 周辺機能インタラプトの使用許可 許可
PIE1 6 ADIE AD変換のインタラプト許可 許可
PIR1 6 ADIF AD変換完了フラグ 完了 未完
ADCON0 7 CHS5 アナログ入力チャネルの指定: (リセット直後は、000000)
000000=ANA0, 010000=ANC0, 010101=ANC5
000001=ANA1, 010001=ANC1, 111101=TMP
000010=ANA2, 010010=ANC2, 111110=DAC
000100=ANA4, 010011=ANC3, 111111=FVR
000101=ANA5, 010100=ANC4, 111100=AVss
1 0
6 CHS4 1 0
5 CHS3 1 0
4 CHS2 1 0
3 CHS1 1 0
2 CHS0 1 0
1 GO/DONE 変換開始/終了 開始 終了
0 ADON ADモジュール On/Off ON OFF
ADCON1 7 ADFM 変換結果の出力フォーマット 右詰 左詰
6 ADCS2 AD変換クロック指定: リセット直後は、<000>
000 =Fosc/2, 010 =Fosc/32, 101 =Fosc/16, 011 =FRC
001 =Fosc/8, 100 =Fosc/4, 110 =Fosc/64, 111 =FRC
1 0
5 ADCS1 1 0
4 ADCS0 1 0
2 ADNREF 基準負電圧指定 外部 Vss
1 ADPREF1 基準正電圧指定: リセット直後は、<00>
00=Vdd, 10=外部Pin, 11=内部基準電圧(FVR)
1 0
0 ADPREF0 1 0
ADACT 4 ADACT4 トリガモード: リセット直後は、<00000>
00000=手動 00100=TMR1 01000=CLC1 11000=CCP1 10000=TMR3
00001=TMR4 00101=TMR2 01001=CLC2 11001=CCP2 10001=TMR5
00010=TMR6 00110=C1 01010=CLC3 11010=CCP3
00011=TMR0 00111=C2 01011=CLC4 11011=CCP4
3 ADACT3
2 ADACT2
1 ADACT1
0 ADACT0
FVRCON 7 FVREN FVR制御 動作 無効
6 FVRRDY (Read Only) FVR状況 常時「1」 使用可 不可
1 ADFVR1 ADC用バッファ出力倍率
11 : x4(4.096V), 10 : x2(2.048v), 01 : x1(1.024v), 00 : OFF(初期値)
0 ADFVR0
FoscとAD変換クロック(TAD)の関連
変換クロック Fosc
ソース ADCS 1M 4M 16M 32M
Fosc/2 000 2.0 uS 500 nS 125 nS 63 nS
Fosc/4 100 4.0 uS 1.0 uS 250 nS 125 nS
Fosc/8 001 8.0 uS 2.0 uS 500 nS 250 nS
Fosc/16 101 16.0 uS 4.0 uS 1.0 uS 0.5 uS
Fosc/32 010 32.0 uS 8.0 uS 2.0 uS 1.0 uS
Fosc/64 110 64.0 uS 16.0 uS 4.0 uS 2.0 uS
FRC x11 1.0-6.0 uS 1.0-6.0 uS 1.0-6.0 uS 1.0-6.0 uS
  • FRCの中心値は、1.6uS
  • Foscが1MHzより遅い場合や、
    Sleep中は、FRCを使用する。
  • 枠内が赤いTADは、動作保障外

A/D変換のプログラム例

PortA - RA2 (ANA2) に続されたボリュームで分圧された電圧をAD変換し、その値をLEDに表示するプログラムです。変換された10ビットの上位4ビットを表示しています。

<回路図>

<プログラム>

//*************************************
 * File: ADC sample
 * System ClockはConfigで内部1MHzに設定
 * ANC0(RC0) の電圧をAD変換、
 * 変換された10ビットの上位4ビットをLED表示
 * PIC16F18346 MPLAB XC8 v2.10
 * Created on May 22, 2020, 2:37 PM
 **************************************/

#include <xc.h>
#define _XTAL_FREQ 1000000      // delay_ms(x) のための定義

#pragma config FEXTOSC = OFF,RSTOSC = HFINT1  // HFINTOSC (1MHz)
#pragma config CLKOUTEN = OFF,CSWEN = OFF,FCMEN = OFF
#pragma config MCLRE = ON,PWRTE = OFF,WDTE = OFF,LPBOREN = OFF
#pragma config BOREN = OFF,BORV = LOW,PPS1WAY = OFF,STVREN = ON
#pragma config DEBUG = OFF
#pragma config WRT = OFF,LVP = ON,CP = OFF,CPD = OFF

#define LED7 LATC5
#define LED6 LATA2
#define LED5 LATA1
#define LED4 LATA5

void LEDout(char data);

void main(void) {

    LATA = 0;
    LATC = 0;
    TRISC = 0b11011111;         // RC5を出力に設定
    TRISA = 0b11011001;         // RA1,2,5を出力に設定
    ANSELA = 0;                 // 全てのpinをデジタルに設定
    ANSELC = 0;

    ANSC0  = 1;                 // ANC0(RC0)はアナログ入力に設定
    ADACT  = 0b00000000;        // AD変換はプログラムの命令で開始
    ADCON1 = 0b00000000;        // 左詰め出力, AD変換クロックFosc/2
                                // 正基準電圧 VDD
    ADCON0 = 0b01000001;        // アナログ入力 ANC0(RC0),ADC ON

    while(1){
        __delay_ms(5);          // ADチャージ時間
        GO = 1;                 // AD変換開始
        while(GO);              // AD変換終了待ち
        LEDout(ADRESH);         // LEDに結果表示
    }
}
// LED D7-D4 に上位4bitを表示
void LEDout(char data){
  if(data & 0x80)LED7 = 1; else LED7 = 0;
  if(data & 0x40)LED6 = 1; else LED6 = 0;
  if(data & 0x20)LED5 = 1; else LED5 = 0;
  if(data & 0x10)LED4 = 1; else LED4 = 0;
}