Trouble with A to D conversion on PIC18F4520

Hi there. I wonder if anyone can help. I’ve been using microcontrollers for a while now, but never for A to D conversion. I’m having difficulty getting to grips with it. I’m including the code here, which is just trying to sample AN0 with a variable resistor tied to vss and vdd on its ends, with the wiper going to pin 2 (AN0). The value is (should be) shown on a LCD display.

I’m using Sourceboost C++ compiler. The chip I’m using is a PIC18F4520. I’ve done bit-wise setting of the adcon0-2 registers, in an effort to make things readable (or maybe not)! Hopefully, someone will point out my stupidity!

Thanks in anticipation...



#include <system.h>
#include <stdio.h>
#include <string.h>
#include <adc.h>

//Those pesky config bits!
#pragma config OSC = HS
#pragma config WDT = OFF
#pragma config PWRT = ON
#pragma config PBADEN = OFF
#pragma config BOREN = OFF
#pragma config LVP = OFF
#pragma CLOCK_FREQ 20000000

extern void init_display(void);
extern void cls(void);
extern void lprint(char*);
extern void gotoxy(char,char);

void main()
{
trisa = 255;
trisb = 0; //Used by display
char disp[80];
unsigned short value; //Value returned by conversion
init_display();
clear_bit(portb,7);
clear_bit (adcon0, CHS0); //AN0
clear_bit (adcon0, CHS1); //
clear_bit (adcon0, CHS2); //
clear_bit (adcon0, CHS3); //

clear_bit (adcon1, PCFG0); //Just AN0 a to d
set_bit (adcon1, PCFG1); //
set_bit (adcon1, PCFG2); //
set_bit (adcon1, PCFG3); //
clear_bit (adcon1, VCFG0); //+ve ref
clear_bit (adcon1, VCFG1); //0v ref

set_bit (adcon2, ACQT0); //Acquisition time
clear_bit (adcon2, ACQT1); //
set_bit (adcon2, ACQT2); //
set_bit (adcon2, ADCS0); //Clock
clear_bit(adcon2, ADCS1); //
set_bit (adcon2, ADCS2); //
set_bit (adcon2, ADFM); //Justification

set_bit(adcon0,ADON); //Turn on
next:
set_bit(adcon0, GO);
wait:
if(test_bit(adcon0, GO != 0)) goto wait;

value = (ADRESH << 8) | ADRESL;
gotoxy(1,1);
sprintf(disp, "Value is: %u. ", value);
lprint(disp);
goto next;

}
You forgot to say what exactly is the problem.
Hi Helios! Whatever the position of the vr, the display just shows 53187. I can even take a test wire from Vss or Vdd to pin 2, without anything happening. I've tried 2 devices (one brand new) just in case the microcontroller was faulty.

I'm sure it's something obvious, but I'm not seeing it right now.
It looks like you made a typo here:
if(test_bit(adcon0, GO != 0))
instead of
if(test_bit(adcon0, GO) != 0)
Although I'd expect that you're waiting for value of bit GO of adcon0 changes to 1, which should be
if(test_bit(adcon0, GO) == 0)

But really, there's no reason to be using goto in the first place.
1
2
3
4
5
6
7
8
9
while (true){
    set_bit(adcon0, GO);
    while (!test_bit(adcon0, GO));

    value = (ADRESH << 8) | ADRESL;
    gotoxy(1,1);
    sprintf(disp, "Value is: %u. ", value);
    lprint(disp);
}

I don't know if there's anything else wrong. That's just what's obviously wrong.
Thanks for that. I set the GO bit on adcon0 to start the reading, and was waiting for the bit to be reset when the data had been acquired. I did change the condition temporarily, but it didn't sort the problem.

I'll certainly tidy the code up, rather than using a "goto spaghetti"!
Last edited on
Topic archived. No new replies allowed.