View previous topic :: View next topic |
Author |
Message |
Christer
Joined: 12 Sep 2003 Posts: 3
|
ADC problems |
Posted: Mon Jan 19, 2004 9:37 am |
|
|
I have a very strange behavior on my ADC on a 18F452:
I use all channels and ref on 3.
I use 10 bits.
My problem is that if channel one get over 256 it spills over to channel two.
The code looks like this:
switch(AnaState)
{
case 0: // Select channel
ADCON0=ANACH0;
AnaState++;
break;
case 1: // Start conversion
AdBusy=1;
AnaState++;
break;
case 2: // Get 10 bit value
ADvalue0=(ADRESH*256)+ADRESL;
AnaState++;
break;
and so on..
Greetings
Chris _________________ Christer TENNSTEDT |
|
|
Neutone
Joined: 08 Sep 2003 Posts: 839 Location: Houston
|
|
Posted: Mon Jan 19, 2004 10:58 am |
|
|
Maybe you could use this
Code: |
#define ADCON0 0xFC2
#bit GO_DONE = ADCON0.2
|
and this
Code: |
While(GO_DONE);
Analog_Input_2_RAW=read_adc(ADC_READ_ONLY);
|
|
|
|
Ttelmah Guest
|
Re: ADC problems |
Posted: Mon Jan 19, 2004 11:12 am |
|
|
Christer wrote: | I have a very strange behavior on my ADC on a 18F452:
I use all channels and ref on 3.
I use 10 bits.
My problem is that if channel one get over 256 it spills over to channel two.
The code looks like this:
switch(AnaState)
{
case 0: // Select channel
ADCON0=ANACH0;
AnaState++;
break;
case 1: // Start conversion
AdBusy=1;
AnaState++;
break;
case 2: // Get 10 bit value
ADvalue0=(ADRESH*256)+ADRESL;
AnaState++;
break;
and so on..
Greetings
Chris |
How fast are you looping?.
It is possible/probable, that if the time is not long enough between the 'select', and the 'read' operation, there may be significant interraction between the channels. Also you do not test if the ADC, has finished it's conversion, when reading, so depending on the 'loop' rate, and the ADC clock, the conversion may not have finished.
You don't actually 'need' to code this yourself, the compiler has the functions to do the required operations seperately.
So:
Code: |
switch(AnaState) {
case 0: // Select channel
set_adc_channel(ANACH0);
AnaState++;
break;
case 1: // Start conversion
read_adc(ADC_START_ONLY);
AnaState++;
break;
case 2: // Get 10 bit value
ADvalue0=read_adc(ADC_READ_ONLY);
AnaState++;
break;
}
//You need to ensure that the loop time here, is long enough to allow the
//input to charge to the incoming voltage (typically in the order of
//perhaps 10uSec), and is also long enough for a conversion to complete.
|
Best Wishes |
|
|
Christer
Joined: 12 Sep 2003 Posts: 3
|
|
Posted: Tue Jan 20, 2004 4:30 am |
|
|
Thanks a lot for your answers.
I was a bit too rapid in my case changing.
Now it works fine. The metod witt the builtin funktions does not work at all. I have tried that earlier. Strange!! _________________ Christer TENNSTEDT |
|
|
|