JH7UBCブログ

アマチュア無線 電子工作 家庭菜園など趣味のブログです

PIC16F1705 ADコンバータ テスト

2019-04-25 11:43:08 | PIC16F1705

 PIC16F1705は、8チャンネルのADコンバータを使うことができます。内部のADコンバータは1つなのですが、下の図のようにADCON0レジスタのCHS<4:0>によってチャンネルを選択します。

   PIC16F1705の説明書から転載

 

 今回のテストでは、AN0とAN1を使い、VREF+はFVR×2=2.048Vとして、AD変換値をI2C LCD AQM0802Aに2つの値を表示してみます。

ブレッドボードです。電源は乾電池2本(3V)です。

 プログラムです。

 AD変換の手順については、PIC12F1822と同じなので、私のホームページ「JH7UBCホームページ」のこの記事を見てください。

 ADコンバータの変換結果(0~1023)は、AQM0802Aの1行目にAN0(CH0)を2行目にAN1(CH1)を0.5秒ごとに表示します。

  AN0とAN1の選択は、ADCON0レジスタのbit2 CHS0で行います。CHS0=0でAN0、CHS0=1でAN1が選択されます。

-----------------------------------------------------------

/*
 * File:   main.c
 * Author: JH7UBC Keiji Hata
 * PIC16F1705 ADC test
 * Created on 2019/04/23
 */
#include <stdio.h>
#include <stdlib.h>
#include <xc.h>
 
// CONFIG1
#pragma config FOSC = INTOSC    //内部クロックを使う
#pragma config WDTE = OFF       //ウォッチドックタイマー無効
#pragma config PWRTE = ON       //パワーアップタイマーを有効にする
#pragma config MCLRE = OFF      //MCLRピンをRA3として使用する
#pragma config CP = OFF         //プログラムメモリを保護しない
#pragma config BOREN = ON       //ブラウンアウトリセットを有効にする
#pragma config CLKOUTEN = OFF   //クロック出力を無効とし、RA4ピンとして使用する
#pragma config IESO = OFF       //内部・外部クロックの切り替えでの起動を行わない
#pragma config FCMEN = OFF      //外部クロックを監視しない
 
// CONFIG2
#pragma config WRT = OFF        //フラッシュメモリを保護しない
#pragma config PPS1WAY = OFF    //ロック解除シーケンスで何度でもPPSLOCKをセット/クリアできる
#pragma config ZCDDIS = ON      //ゼロクロス検出回路無効
#pragma config PLLEN = ON       //×4PLLを動作させる
#pragma config STVREN = ON      //スタックオーバーフローリセットを行う
#pragma config BORV = HI        //ブラウンアウトリセット電圧を高(2.7V)に設定
#pragma config LPBOR = OFF      //低消費電力ブラウンアウトリセット無効
#pragma config LVP = OFF        //低電圧プログラミングを行わない
#define _XTAL_FREQ 32000000     //クロック32MHz
 
/* LCD関係定義 */
#define LCD_addr 0x7C   //3E+0
#define LCD_LINE1 0x80
#define LCD_LINE2 0xC0
 
/* I2C 初期化*/
void I2C_init(){
    SSP1CON1 = 0x28;        //SSPEN = 1,I2C Master Mode
    SSP1STATbits.SMP = 1;   //標準速度モード(100KHz)
    SSP1ADD = 0x4F;         //Fosc/(4*Clock)-1  Clock=100kHz,Fosc=32MHz
}
 
/* スタートコンディション */
void I2C_start(){
    SSP1CON2bits.SEN = 1;
    while(SSP1CON2bits.SEN);
}
 
/* ストップコンディション */
void I2C_stop(){
    SSP1IF = 0;
    SSP1CON2bits.PEN = 1;
    while(SSP1CON2bits.PEN);
    SSP1IF = 0;
}
 
/* I2Cに1byte送信 */
void I2C_write(unsigned char dat){
    SSP1IF = 0;
    SSP1BUF = dat;
    while(!SSP1IF);
}
 
/* write command */
void LCD_cmd(unsigned char cmd){
    I2C_start();          //start condition
    I2C_write(LCD_addr);  //send slave address
    I2C_write(0x00);      //send control byte
    I2C_write(cmd);       //send command
    I2C_stop();           //stop condition
}
 
/* write charactor */
void LCD_char(unsigned char dat){
    I2C_start();          //start condition
    I2C_write(LCD_addr);  //send slave address
    I2C_write(0x40);      //send control byte
    I2C_write(dat);       //send data
    I2C_stop();           //stop condition
}
 
/* LCD initialize */
void LCD_init(){
    __delay_ms(40); //40ms wait
    LCD_cmd(0x38);  //8bit,2line
    LCD_cmd(0x39);  //IS=1 : extention mode set
    LCD_cmd(0x14);  //Internal OSC Frequency
    LCD_cmd(0x70);  //Contrast set
    LCD_cmd(0x56);  //Power/ICON/Contrast Control
    LCD_cmd(0x6C);  //Follower control
    __delay_ms(200);//200ms wait
    LCD_cmd(0x38);  //IS=0 : extention mode cancel
    LCD_cmd(0x0C);  //Display ON
    LCD_cmd(0x01);  //Clear Display
    __delay_ms(2);  //wait more than 1.08ms
}
 
/* Clear Display */
void LCD_clear(){
    LCD_cmd(0x01);
    __delay_ms(1);
    __delay_us(80);
}
 
/* Return Home `*/
void LCD_home(){
    LCD_cmd(0x02);
    __delay_ms(1);
    __delay_us(80);
}
 
/* Locate cursor x,y */
void LCD_cursor(unsigned char x,unsigned char y){
    if (y == 0){
        LCD_cmd(LCD_LINE1+x);
    }
    if (y == 1){
        LCD_cmd(LCD_LINE2+x);
    }
}
 
/* write 1 charactor to LCD  */
void putch(unsigned char ch){
    LCD_char(ch);
}
 
/* ADconvert & display*/
void AD_convert(unsigned char channel){
    ADCON0bits.CHS0 = channel;   //ADC チャンネルセレクト
    __delay_us(20);         // 20us待つ
    GO = 1;                 // ADC スタート
    while(GO);              // AD変換終了まで待つ
    unsigned int val = (ADRESH << 8)| ADRESL;   //AD変換結果をvalに入れる
    LCD_cursor(3,channel);
    printf("%5d",val);      // AD変換結果を表示
}
 
void main() {
    OSCCON = 0b01110000;    // 内部クロック8MHz ×4=32MHz
    ANSELA = 0b00000011;    // AN0-AN1を使う。他はデジタル
    ANSELC = 0b00000000;    // AN4-AN6を使わない
    TRISA  = 0b00000011;    // RA0,RA1は入力、他は出力
    TRISC  = 0b00000011;    // RC0,RC1は入力、他は出力
    PORTA  = 0b00000000;    // PORTAクリア
    PORTC  = 0b00000000;    // PORTCクリア
   
    /* ADコンバータ設定*/
    ADCON0 = 0b00000001;    // bit0=1 ADCを有効にする
    ADCON1 = 0b10100011;    // bit7(ADFM)=1(右詰め),bit<6:4>=010 Fosc/32=1.0us
                            // bit<1:0>=00 VREF+=FVR
    FVRCON = 0b10000010;    // bit7(FVRON)=1,bit<1:0>=10 ADFVR×2=2.048V
   
    /* I2Cピン設定 */
    RC0PPS = 0x10;   //RC0をSCLに割り当てる(出力)
    SSPDATPPS = 0x11;//SSPDATにRC1を割り当てる(入力)
    RC1PPS = 0x11;   //RC1をSDAに割り当てる(出力)
   
    I2C_init();     // I2C初期化
    LCD_init();     // LCD初期化
   
    /* 表示初期設定*/
    LCD_home();
    printf("CH0");
    LCD_cursor(0,1);
    printf("CH1");
   
    while(1){ 
        AD_convert(0);  //channel0をAD変換・表示
        AD_convert(1);  //channel1をAD変換・表示
        __delay_ms(500);
    }
}
 

最新の画像もっと見る

コメントを投稿