2021年8月29日日曜日

PIC16F1829でアナログ値を読み取る


背景

PICマイコン(PIC16F1829)でのアナログ値を読み取りは、Arduinoほど単純ではありませんでしたが、データシートを読み解くことで期待するように読めました。
備忘録を兼ねてプログラムと設定方法を記事に残します。

使ったもの

  • PIC16F1829
  • PicKit4
  • MplabXとXC8コンパイラをインストールしたPC
    Ubuntuへのインストール方法は以前書いた下記の記事が参考になると思います。
    Ubuntuに開発環境を作り、PIC16F1829でLチカする方法
  • ブレッドボード
  • 可変抵抗
  • ワイヤー
  • ジャンパワイヤ
  • コンデンサ 0.1uf
  • ピンヘッダ
  • はんだごて + はんだ
    可変抵抗とピンヘッダへのワイヤーの接着に利用しました。

回路

RC5でLEDを点滅させ、RC7をアナログピン(AN9)として動かします。
電源はPicKit4から給電します。


組み立てるとこうなりました。




プログラム

今回はanalog_readというプロジェクトを作り、それに下記の内容のmain.cを配置しました。
プロジェクトの作り方はLEDを点滅させた時の記事が参考になります。

利用したコンパイラはXC8のv2.20です。


main.cはプロジェクト新規作成時は存在しないので、Source Filesを右クリックして作成します。


main.c
#include <xc.h>
#include <pic16f1829.h>
#include <stdint.h>
#define I2C_ADDRESS 0x10
#define _XTAL_FREQ 16000000
#define LED_ON 1
#define LED_OFF 0
#pragma config FOSC=INTOSC, WDTE=OFF, PWRTE=OFF, MCLRE=OFF, CP=OFF, CPD=OFF, BOREN=ON, CLKOUTEN=OFF, IESO=OFF, FCMEN=OFF
#pragma config WRT=OFF, PLLEN=OFF, STVREN=OFF, LVP=OFF

#define LED_BIT LATCbits.LATC5

unsigned char analogL = 0, analogH = 0;

void main(void) {
OSCCONbits.IRCF = 0b1111; // 16MHz
OSCCONbits.SCS = 0b11; // Use internal oscillator as system clock
// Set port c as output
TRISC = 0x00;
LATC = 0x00;

// Analog read by RC7 AN9
TRISCbits.TRISC7 = 1; // set as input
ANSELCbits.ANSC7 = 1; // activate analog
ADCON0 = 0b00100111; // use AD converter with port 9
ADCON1 = 0b10000000; // configure something

while(1) {
if (ADCON0bits.GO_nDONE == 0) {
// unsigned short is 16 bit
unsigned short analog = ADRES;
analogL = ADRESL;
analogH = ADRESH;
if (analog > 500) {
LED_BIT = 1;
} else {
LED_BIT = 0;
}
ADCON0bits.GO_nDONE = 1;
}
}
}

アナログ読込に関する要所を解説します。

TRASCの7を1にして読込用のピンとして設定し、ANSELCの7を1にしてアナログ読込を有効にします。
    TRISCbits.TRISC7 = 1; // set as input
ANSELCbits.ANSC7 = 1; // activate analog

データシートのADCON0の説明に従い、RC7に割り当てられているAD9を有効にします。


RC7はAN9が繋がっているので、bit6-2は01001にします。


DO_DONEとADONを両方1にしてアナログ読込を有効化します。
DO_DONEは読取りが終わると0になるので、while文の中で必要に応じて1にします。


    ADCON0 = 0b00100111; // use AD converter with port 9

データシートのADCON1の説明に従い、ビットは右寄せ、更新頻度は最も低く、電圧下限はVSS、電圧上限はVDDと設定します。


    ADCON1 = 0b10000000; // configure something

while文の中でDO_DONEが0になったら価を処理し、DO_DONEを再び1に戻して測定を再開します。
    while(1) {
if (ADCON0bits.GO_nDONE == 0) {
// unsigned short is 16 bit
unsigned short analog = ADRES;
// do something
ADCON0bits.GO_nDONE = 1;
}
}

測定した価が500異常だったらLEDを光らせます。
            unsigned short analog = ADRES;
analogL = ADRESL;
analogH = ADRESH;
if (analog > 500) {
LED_BIT = 1;
} else {
LED_BIT = 0;
}

デバッガを利用しつつ動作確認

ADRESを代入する行でブレークポイントを有効にします。
行番号をクリックすると数字が四角に変わるので、そうなっている行がブレークポイントとなります。


PicKitをPCに接続した状態でデバッグボタンを押して動作確認を開始します。


ブレークポイントで止まると行が緑色になり、マウスカーソルを変数に重ねるとその時点での価を確認できます。
VDDとRC7の間の抵抗を最小にしたときは、アナログ読込値の最大である0x03ffが測定されていました。


mplabのツールバーの再生ボタンを押すと、ブレークポイントを抜けて動作が進みます。


analogが500よりも大きいので、LEDが点灯します。


VDDとRC7の間の抵抗を最大にしたとき(RC7とGNDの間の抵抗がほぼ0のとき)は、アナログ読込値のとして0x0006が測定されていました。


mplabのツールバーの再生ボタンを押すと、ブレークポイントを抜けて動作が進みます。


analogが500より小さいので、LEDは点きません。


期待通りに動きました。

まとめ

PIC16F1829でアナログ値を読み取れました。
常時監視したい場合は、アナログ読取り修了フラグを監視して無効になったら有効にして読み取りを繰り返させる必要があると分かりました。

0 件のコメント :