PIC 16F690 7 seg voltmeter

Introduction

This little program reads analog voltage on AN2, and converts it into an ADC value, and then claculates the volt, The volt is displayed on a 3 digit 7 seg.

Check out this article for the schematic.

#include <xc.h>

// CONFIG
#pragma config FOSC = XT        // Oscillator Selection bits (HS oscillator: High-speed crystal/resonator on RA4/OSC2/CLKOUT and RA5/OSC1/CLKIN)
#pragma config WDTE = OFF       // Watchdog Timer Enable bit (WDT disabled and can be enabled by SWDTEN bit of the WDTCON register)
#pragma config PWRTE = OFF      // Power-up Timer Enable bit (PWRT disabled)
#pragma config MCLRE = OFF      // MCLR Pin Function Select bit (MCLR pin function is digital input, MCLR internally tied to VDD)
#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 Reset Selection bits (BOR disabled)
#pragma config IESO = ON       // Internal External Switchover bit (Internal External Switchover mode is disabled)
#pragma config FCMEN = ON      // Fail-Safe Clock Monitor Enabled bit (Fail-Safe Clock Monitor is disabled)

// DEFINITIONS
#define _XTAL_FREQ 8000000
#define deci_digit PORTBbits.RB4    // Decimal
#define ones_digit PORTBbits.RB5    // One's
#define tens_digit PORTBbits.RB6    // Ten's

// VARIABLES
unsigned char   binary_pattern[]={0b00111111,0b00000110,0b01011011,0b01001111,0b01100110,0b01101101,0b01111101,0b00000111,0b01111111,0b01101111};
unsigned char   binary_pattern_dp[10]= {0b10111111,0b10000110,0b11011011,0b11001111,0b11100110,0b11101101,0b11111101,0b10000111,0b11111111,0b11101111};    // with dp turn on
unsigned int    tens_value, ones_value, deci_value;
unsigned int    voltage;
unsigned int    adc_value;
long            tlong;

// FUNCTIONS
// Functio to initialize the ADC part of the PIC
void adc_init(void) {
    ADCON0bits.ADFM     = 1;        // Right justify
    ADCON0bits.VCFG     = 0;        // VDD as reference
    ADCON0bits.CHS      = 0b0010;   // Analog channel AN2
    ADCON0bits.ADON     = 1;        // ADC enable
    ADCON1bits.ADCS     = 0b010;    // ADC conversion set bit  
}

// Function to do the ADC
void adc_read(void) {
    ADCON0bits.GO       = 1;            // Start ADC
    __delay_us(10);
    while (ADCON0bits.nDONE);           // Wait for ADC to finish
    adc_value = ADRESL + (ADRESH * 256);   
}

// Main program
void main(void) {
    CM1CON0 = 0;            // Disable the comparators
    CM2CON0 = 0;            // Disable the comparators

    PORTA   = 0b00000000;   // All bits LOW
    TRISA   = 0b00000100;   // Setting RA2/AN2 as input

    PORTB   = 0b00000000;   // All bits LOW
    TRISB   = 0b00000000;   // All bits output

    PORTC   = 0b00000000;   // All bits LOW
    TRISC   = 0b00000000;   // All bits output

    ANSEL   = 0b00000100;   // Enabling input buffer on AN2
    ANSELH  = 0b00000000;   // Disable all input buffers

    adc_init();             // Initialize the ADC module

    deci_digit = 0; // Decimal
    ones_digit = 0; // One's
    tens_digit = 0; // Ten's

    while (1) {
        adc_read();
        tlong = (float)adc_value*4.88;
        voltage = tlong;

        tens_value = voltage/1000;
        ones_value = ((voltage/100)%10);
        deci_value = ((voltage/10)%10);

        // Decimal number
        PORTC = binary_pattern[deci_value];
        deci_digit=1;
        __delay_ms(5);
        deci_digit=0;

        // One's number
        PORTC = binary_pattern_dp[ones_value];
        ones_digit = 1;
        __delay_ms(5);
        ones_digit = 0;

        // Ten's number
        PORTC = binary_pattern[tens_value];
        tens_digit = 1;
        __delay_ms(5);
        tens_digit = 0;
    }
    return;
}

My notes and a work in progress.

blogroll

social