PIC 16F688 ADC demo.

PIC 16F688 ADC

This is a little ADC demo, based on the PIC 16F688. I'm using 8-bit analog converter, that's 255, not the 1023 a 10-bit has.

// INCLUDE LIBRARIES
#include <xc.h>
#include <stdio.h>
#include <stdlib.h>

// CONFIGURATION BITS
#pragma config FOSC = HS        // Oscillator Selection bits (INTOSCIO oscillator: I/O function on RA4/OSC2/CLKOUT pin, I/O function on RA5/OSC1/CLKIN)
#pragma config WDTE = OFF       // Watchdog Timer Enable bit (WDT enabled)
#pragma config PWRTE = ON       // Power-up Timer Enable bit (PWRT disabled)
#pragma config MCLRE = ON       // MCLR Pin Function Select bit (MCLR pin function is MCLR)
#pragma config CP = OFF         // Code Protection bit (Program memory code protection is disabled)
#pragma config CPD = OFF        // Data Code Protection bit (Data memory code protection is disabled)
#pragma config BOREN = ON       // Brown Out Detect (BOR enabled)
#pragma config IESO = ON        // Internal External Switchover bit (Internal External Switchover mode is enabled)
#pragma config FCMEN = ON       // Fail-Safe Clock Monitor Enabled bit (Fail-Safe Clock Monitor is enabled)

// DEFINITIONS
#define _XTAL_FREQ 4000000

// GLOBAL VARIABLES
/*
unsigned int adc_raw;
unsigned int mV;
unsigned int result;
*/
short raw_adc, mV, V, Vtenth, result;

short x, y, z;

// FUNCTION PROTOTYPES
void osc_tune(void);
void init_adc(void);
void read_adc(void);
void uart_init(void);
void putch(unsigned char byte);


// FUNCTIONS
// Oscillator tuning
void osc_tune(void) {
    OSCCONbits.IRCF0    = 0b110;    // Internal Osc Freq Select bit => 4MHz
    OSCCONbits.HTS      = 1;        // Status bit, high freq => Stable
    OSCCONbits.OSTS     = 1;        // Osc startup time out => dev run from external
    OSCCONbits.LTS      = 1;        // Low freq bit => stable
    OSCCONbits.SCS      = 0;        // External osc used for system clock

}

// Initialize the ADC module
void init_adc(void) {
    ADCON0bits.ADFM = 1;        // Right justified
    ADCON0bits.VCFG = 0;        // Voltage ref => VDD
    ADCON0bits.CHS  = 0b111;    // Analog channel => AN7
    ADCON0bits.ADON = 1;        // ADC enable bit
    ADCON1bits.ADCS = 0b000;    // A/D Conversion clock bit

}

// Read the ADC port
void read_adc(void) {
    ADCON0bits.GO = 1;          // A/D Conversion is in progress
    __delay_us(10);
    while (ADCON0bits.nDONE);   // Wait for AD to complete
}

// Configuring the ESUART port
void uart_init(void){
/*
 4MHz
 * 16000000 / 9600 = 1666.6666
 * 1666.6666 / 64 = 26.0416
 * 26.0416 - 1 = 25.0416
 * 25.0416 = 25
 */
    TXSTAbits.BRGH = 1;     // Setting BRGH to use LOW speed
    TXSTAbits.SYNC = 0;     // Setting async mode
    TXSTAbits.TX9 = 0;      // Setting 8-bit transmission
    RCSTAbits.CREN = 1;     // Enable continious receive

    SPBRG = 25;             // Setting the SPBRG register to use 16MHz with BRGH 0

    PIE1bits.RCIE = 1;      // USART receive interrupt enable
    RCSTAbits.SPEN = 1;     // Enable serial port
    TXSTAbits.TXEN = 1;     // Enable transmit
}

// Adding New line and Carrier return
void putch(unsigned char byte){     // Adding Carrier Return and Line feed
    while(!TXSTAbits.TRMT);
    TXREG = byte;
    if ('\n'==byte){
        while (!TXSTAbits.TRMT);
       TXREG = '\r';
    }
    return;
}

// MAIN PROGRAM
void main(void) {

    ANSEL = 0b00000000;     // Disable all analog inputs
    ANSELbits.ANS7 = 1;     // Enabling analog input on AN3

    TRISA = 0b00000000;     // Set TRISA to output

    TRISC = 0b00000000;     // Set TRISC to output
    TRISCbits.TRISC3 = 1;   // Enable input on RC3/AN7

    CMCON0 = 0x07;          // Disable comparators

    osc_tune();

    init_adc();

    uart_init();

    __delay_ms(2000);
    printf("\n\nADC test\n");

    while (1) {
        read_adc();                     // Read the ADC value

        x = ADRESH;                     // A/D High 
        y = ADRESL;                     // A/D Low
        raw_adc = (x << 6) | (y >> 2);  // Combine ADRESH & ADRESL to ADC
        mV = (4900/255) * raw_adc;      // Calculate the millivolt
        V = mV /1000;                   // Calculate the volt
        Vtenth = mV % 1000;             // Calculate the remainder
        printf("ADC: %d\tmV: %d\tV: %d.%d\n", raw_adc, mV, V, Vtenth); // Print everything
        __delay_ms(1000);               // Wait a sec
    }
}

blogroll

social