View previous topic :: View next topic |
Author |
Message |
astus
Joined: 17 Nov 2003 Posts: 12 Location: Australia
|
ADC reading LOW |
Posted: Tue Mar 29, 2005 9:56 am |
|
|
Hi,
I am having a problem with a pic16f819 reading the ADC. The value is allwways far too low. This is using either the vref tied to 5v and gnd or all analog with the internal Vdd and vss ref. The code is below
void main () {
long int volts; //Stores current channel voltage in use
long int max_volt = 0;
int state = MEASURE;
short int max_flag = FALSE;
long int timer;
short int led_flag = FALSE;
int16 test;
setup_oscillator( OSC_1MHZ );
setup_adc_ports( AN0_AN1_AN4_VREF_VREF );
setup_adc( ADC_CLOCK_INTERNAL );
do {
set_adc_channel( 0 ); //Set ADC Channel
// delay_us( ADC_SETTLE ); //Wait for ADC Channel to Settle
test = read_adc();
} while(TRUE);
}
The input has a 1uf and 100 nf cap and is is a voltage divison down and clamped with a 5v1 zener. A typical voltage reading at the adc input is 4.2 volts and the icd debugger shows the value read out to be 218 steps of 218*5/1024 = 1.06V Any hints? |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Mar 29, 2005 10:07 am |
|
|
Quote: |
A typical voltage reading at the adc input is 4.2 volts and the icd debugger
shows the value read out to be 218 steps of 218*5/1024 = 1.06V |
The ratio of 4.2v to 1.06v should be a real big clue. It's about 4:1.
Anytime you see an error in the computer world that is a power of 2,
you should immediately start looking at a bit-shift problem.
Look in the CCS manual at read_adc() function, especially with
respect to the #device adc statement. |
|
|
astus
Joined: 17 Nov 2003 Posts: 12 Location: Australia
|
|
Posted: Tue Mar 29, 2005 4:59 pm |
|
|
YEah I found the ADC=10 , I also passed the read_adc() to a long, the adc is reading correclty but the complier is not taking the upper bits from the adc high register. I also tried using the #BYTE command to specifiy the high and low of ADC then tried using the make16(). The compilier seems to ignore the make16() command completely?
IT seems that long integers are not being passed proplery? anybody got a clue?
By the way I'm using the latest pcm compilier, got it last week.
Thanks
Adam |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Mar 29, 2005 5:15 pm |
|
|
Quote: | the complier is not taking the upper bits from the adc high register. |
Here is the code from PCM vs. 3.222. It looks OK to me.
Code: | 0000 00258 .................... result = read_adc();
000C 1283 00259 BCF 03.5 // Bank 0
000D 151F 00260 BSF 1F.2 // Set Go bit = 1
000E 191F 00261 BTFSC 1F.2 // Wait until conversion is done
000F 280E 00262 GOTO 00E
0010 1683 00263 BSF 03.5 // Bank 1
0011 081E 00264 MOVF 1E,W // Read ADRESL (0x9E)
0012 1283 00265 BCF 03.5 // Bank 0
0013 00A1 00266 MOVWF 21 // Put ADRESL into LSB of result
0014 081E 00267 MOVF 1E,W // Read ADRESH
0015 00A2 00268 MOVWF 22 // Put ADRESH into MSB of result |
I wonder if you're doing the #device adc=10 correctly. The #device
line should be placed immediately below the #include line for the PIC.
Example:
Code: | #include <16F819.H>
#device adc=10 |
|
|
|
future
Joined: 14 May 2004 Posts: 330
|
|
Posted: Tue Mar 29, 2005 6:40 pm |
|
|
5v1 zeners will start to clamp below 5.1volts, remove them and you will see the correct values. |
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Tue Mar 29, 2005 7:02 pm |
|
|
future wrote: | 5v1 zeners will start to clamp below 5.1volts, remove them and you will see the correct values. |
Not all zeners work the same. We had some manufacturers that we had to put on the "blacklist" because they let too much current before they should have. This cause too big a voltage drop and we couldn't obtain high enough readings. |
|
|
future
Joined: 14 May 2004 Posts: 330
|
|
Posted: Tue Mar 29, 2005 7:43 pm |
|
|
I was never able to use 5v1 zeners successfully and ended removing them from the board.
Protection is done by the PIC itself, with a 1k current limit resistor and a 100nf cap to ground. |
|
|
astus
Joined: 17 Nov 2003 Posts: 12 Location: Australia
|
|
Posted: Wed Mar 30, 2005 3:37 am |
|
|
Thanks guys, The adc is actually reading correctly as shown in the special function registers. It is the compilier that seems to confusing the longs and ints. I will move the #device command under the include and see if that helps. Once again thanks for your support.
Regards
Adam |
|
|
JohnKennedy
Joined: 12 May 2004 Posts: 38
|
|
Posted: Wed Mar 30, 2005 3:46 am |
|
|
Hi you need to include the following in the header file or it will default to working in 8 bit mode
Code: | #DEVICE *=16 ADC=10 |
I use this using the 16F818 with no problems
HTH
JFK |
|
|
|