0
\$\begingroup\$

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.

\$\endgroup\$
  • 1
    \$\begingroup\$ Read the value in the adc and calculate what the voltage is. Take a measurement with a meter and see if the calculation and the measurement works. \$\endgroup\$ – efox29 Oct 4 '15 at 3:44
  • \$\begingroup\$ That is what I am asking, how do I read the value from adc??. I have stored the value from ADRESH to a temp variable, but how do I get to know what value is presently stored in the temp?. Rest calculations I know how to do to validate. \$\endgroup\$ – PsychedGuy Oct 4 '15 at 3:54
  • \$\begingroup\$ One possible way may be by interfacing an lcd and displaying the adc results. Is there any other way this can be done?. \$\endgroup\$ – PsychedGuy Oct 4 '15 at 3:55
  • 1
    \$\begingroup\$ Use a breakpoint within the MPLABX and look at the variable in MPLABX. \$\endgroup\$ – efox29 Oct 4 '15 at 3:58
  • \$\begingroup\$ Ok will do that. \$\endgroup\$ – PsychedGuy Oct 4 '15 at 4:34
2
\$\begingroup\$

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
\$\endgroup\$
  • \$\begingroup\$ Isn't the code in your answer the same as the one I have written?, I cant see any difference, can you please clarify on this. And yes, that's simple and good way to check the ADC data, will do that. \$\endgroup\$ – PsychedGuy Oct 4 '15 at 14:06
  • 1
    \$\begingroup\$ The difference is the ; at the end of the first line. Your code executes the second line in the while loop, Bruce's code has an empty loop and sets the ADIF after. It's equivalent to while(!PIR1bits.ADIF){} while yours is while(!PIR1bits.ADIF){PIR1bits.ADIF = 0;} \$\endgroup\$ – sweber Oct 4 '15 at 20:14
  • \$\begingroup\$ Ok. That makes it clear. \$\endgroup\$ – PsychedGuy Oct 5 '15 at 3:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.