8/29/2009

Using the DAC on a PIC18F2*550

I tried to figure out how to use the integrated DAC. I have a 2k7 Potentiometer (unfortunately, a non-linear one) connected between Vdd and Vss, the terminal goes to AN0. AN1:AN6 drive 6 LED to form a simple bar-graph display showing the captured voltage.

#include <p18cxxx.h>
#include <delays.h>

#pragma config MCLRE = ON      //MCLR pin enabled; RE3 digital input disabled
#pragma config WDT = OFF       //HW Disabled - SW Controlled
#pragma config BOR = OFF       //Brown-out Reset disabled in hardware and software 

#pragma config FOSC = INTOSCIO_EC     //Internal oscillator, port function on RA6, EC used by USB 
#pragma config LVP = OFF              //Single-Supply ICSP disabled, free RB5
#pragma config PBADEN = OFF           //RB0 through RB4 pins are configured as digital I/O on Reset
#pragma config DEBUG = OFF            //Background debugger disabled, RB6 and RB7 configured as I/O pins

void init (void);
void main (void);

void init (void)
{
    OSCCON = 0xFF;    //internal oscillator at 8MHz
                      //1ms = 2000000 Instructions

    ADCON0 = 0x01;    //Enable ADC on Channel AN0
    ADCON1 = 0x0E;    //ADC on AN0, VDD and VSS reference
    ADCON2 = 0xA7;    //Right justified, 8TAD, FRC Clock
}

void main (void)
{

    int adc;

    init();
    TRISA = 0x00;
    LATA = 0x7E;    //1st bit used by ADC, last bit non existent

    while (1)
    {
        ADCON0bits.GO_DONE = 1;            //Start the DAC
        while (ADCON0bits.GO_DONE) {}      //Wait for the DAC to finish calculating
        adc = ADRESL + (ADRESH * 256);     //Add the two 8-bit registers into one Integer
        //LATA = (adc / 16) << 1;          //for testing, you can output the value
                                           //in binary

        if (adc  >= 876)                   //6 LED + Off = 7 states
        {LATA = 0x7E;}                     //adc >= 6/7*1023, adc >= 5/7*1023 and so on.
        else if (adc  >= 730)
        {LATA = 0x3E;}                     //Light 6 LED
        else if (adc  >= 584)
        {LATA = 0x1E;}                     //Light 5 LED
        else if (adc  >= 438)
        {LATA = 0x0E;}                     //...
        else if (adc  >= 292)
        {LATA = 0x06;}
        else if (adc  >= 146)
        {LATA = 0x02;}
        else
        {LATA = 0x00;}
          
        Delay10KTCYx(1);    //According to the datasheet, we only have to wait
                            //4 instructions after collecting data
     }
}

Test circuit:

Keine Kommentare: