Not able to understand the behaviour of PIC18F458 ADC output on PORT B with LED’s

adccpic

I have recently started meddling with the PIC18f458. The below shows the code in which I have configured the internal 10 bit adc.

#define _XTAL_FREQ 10000000
#include<P18F458.h>
#include <xc.h>
#pragma config OSC=HS
#pragma config WDT=OFF
#pragma config LVP=OFF


void main (void)
{
TRISAbits.TRISA0 = 1;       //Configure RA0 pin on PORTA as Input
TRISB = 0;


//ADC Configuration
ADCON1bits.PCFG3 = 1;       /*Configure AN0 as input channel and select 
ADCON1bits.PCFG2 = 1;          +VREF = VDD = 5V and -VREF = VSS = 0V*/
ADCON1bits.PCFG1 = 1;
ADCON1bits.PCFG0 = 0;
ADCON1bits.ADFM = 0;         //Store 8 bit in ADRESH and 2 bits in ADRESL

ADCON0bits.CHS0 = 0;       // Select AN0 as the input channel
ADCON0bits.CHS1 = 1;
ADCON0bits.CHS2 = 1;

ADCON0bits.ADCS1 = 1;              
ADCON0bits.ADCS0 = 1;

ADCON0bits.ADON = 1;      //Turn ON ADC
PIR1bits.ADIF = 0;        //AD Interrupt Flag
PIE1bits.ADIE = 1;        //Enable AD interrupt
INTCONbits.GIE = 1;       //Enable Global Interrupts

ADCON0bits.GO = 1;        //Start AD Conversion

while(!PIR1bits.ADIF);    
    PIR1bits.ADIF = 0;
while(1)
{

temp = 0;
ADCON0bits.GO = 1;
while(!PIR1bits.ADIF);     //Wait till conversion is completed
PIR1bits.ADIF = 0;        //If completed, clear ADIF bit
PORTB = ADRESH;            //Copy digital data to temp variable
}

I have done the following changes within the code and, as advised, I connected 8 LED's to PORTB in order to check the adc 8 bit output from ADRESH, however, the LEDS are behaving weirdly. The first 4 LEDS connected to PORT – B0,B1,B2 and B3 are constantly ON irrespective to how I vary the input 10K POT while among the last 3 LEDS, one keeps blinking and the second last two LEDS sometimes switch oFF and ON while varying the POT. Can anyone tell me whats happening?. Is there something wrong with the code?

At present I am also working on setting up UART to stream this data for better analysis. In the mean time, any help and guidance regarding this would be appreciated. Thank you all.

Best Answer

One simple way to see the value of ADRESH might be to send it to PORTB (configured as an 8 bit output port) then monitor the voltages on each pin with a meter or LEDs.

You may find it isn't working because this code,

while(!PIR1bits.ADIF)    
    PIR1bits.ADIF = 0;

is a loop that continuously resets the ADC interrupt flag until it becomes set. Problem is the flag may become set after being tested but before being reset, then your code gets stuck in the loop. If it manages to break out of the loop then the flag doesn't get reset, and you read the ADC result before it is ready.

What you want is this:-

while(!PIR1bits.ADIF);   // wait until ADC int flag is set 
PIR1bits.ADIF = 0;       // clear ADC int flag