PDA

View Full Version : 16F819 ADC problems



MUC
- 17th April 2005, 19:15
I can not get the 10-bit A/D working correctly. The program below reads AN0 and turns an LED on if the voltage drops below half of VDD. At least that is what I want it to do. I am expecting to see a result of 1024 at 5 volts and 512 at 2.5 volts. The problem I am having is I don’t get 1024 or even close. If I DEFINE ADC_BITS 10 then the result is over 64000 at 5 volts. If I leave the DEFINE ADC out of the program I get 256 at 5 volts. I don’t know what is going on. Why don’t I get 1024 at 5V? I have been reading the data sheet for over an hour and have not been able to figure this out. The program is below.

Thanks,
Mark

DEFINE OSC 20

' Define ADCIN parameters
Define ADC_BITS 10 ' Set number of bits in result
' Define ADC_CLOCK 3 ' Set clock source (3=rc)
Define ADC_SAMPLEUS 50 ' Set sampling time in uS

ADCON0 = %1000101 '
ADCON1 = %1000010 ' AN4-AN0 A,A,A,A,A right justify
TRISA.0 = 1
TRISA.1 = 1

' TRISB.4 = 0 ' Set PORTB.4 to output
' TRISB.5 = 0 ' Set PORTB.5 to output
' TRISB.3 = 0 ' Set PORTB.3 to output

adval1 var word
adval2 var word

clear
High PORTB.5 ' Turn on run LED
low PORTB.4

loop:
ADCIN 0, adval1 ' Read AN0
' adcin 1, adval2 ' Read AN1

if adval1 < 512 then
high PORTB.4
else
low PORTB.4
endif

serout2 PORTB.3,16572,["ADVAL_1 = ",dec adval1,13,10]
pause 100
goto loop
End

mister_e
- 17th April 2005, 19:57
For sure you don't read the good pin. Must use the pin name or alias.

something like ADCIN PORTA.0, adval

MUC
- 17th April 2005, 20:31
Hmm, the method I’m using to read the A/D is used on the melabs examples page. I have also used this method with a 16F688 without problems. I do get a varying number when I adjust a pot on the pin (0-256) for the 16F819. I need the 1024 resolution or I could use it as is. Something is setup wrong but I think I’m reading the A/D correctly. Correct me if I'm wrong. I will give your advice a try in a bit.

Thanks,
Mark

A melabs example;

' Read an analog voltage on RA0 and send the decimal representation
' of the value on the serial port at 2400 baud. 10-bit conversion
' yields 0-1023 result for 0-5 volt input.

' Define LOADER_USED to allow use of the boot loader.
' This will not affect normal program operation.
Define LOADER_USED 1

' Define ADCIN parameters
Define ADC_BITS 10 ' Set number of bits in result
Define ADC_CLOCK 3 ' Set clock source (3=rc)
Define ADC_SAMPLEUS 50 ' Set sampling time in uS

adval var word ' Create adval to store result


TRISA = %11111111 ' Set PORTA to all input
ADCON1 = %10000010 ' Set PORTA analog and right justify result

loop: ADCIN 0, adval ' Read channel 0 to adval

Serout2 PORTC.6,396,["Value: ",DEC adval,13,10] ' Display value

Pause 100 ' Wait .1 second

Goto loop ' Do it forever
End

MUC
- 17th April 2005, 20:57
Unfortunately your suggestion did not work. Here are some captured results. Starts with reading on ground, then roughly 2.5V then VDD (5V);

ADVAL_1 = 0
ADVAL_1 = 0
ADVAL_1 = 0
ADVAL_1 = 0
ADVAL_1 = 0
ADVAL_1 = 0
ADVAL_1 = 0
ADVAL_1 = 0
ADVAL_1 = 0
ADVAL_1 = 0
ADVAL_1 = 0
ADVAL_1 = 0
ADVAL_1 = 0
ADVAL_1 = 0
ADVAL_1 = 0
ADVAL_1 = 0
ADVAL_1 = 30912
ADVAL_1 = 31168
ADVAL_1 = 31104
ADVAL_1 = 31168
ADVAL_1 = 31040
ADVAL_1 = 31104
ADVAL_1 = 31040
ADVAL_1 = 31104
ADVAL_1 = 31168
ADVAL_1 = 31232
ADVAL_1 = 31040
ADVAL_1 = 31104
ADVAL_1 = 31104
ADVAL_1 = 31104
ADVAL_1 = 31040
ADVAL_1 = 31104
ADVAL_1 = 31104
ADVAL_1 = 31232
ADVAL_1 = 31104
ADVAL_1 = 31168
ADVAL_1 = 65216
ADVAL_1 = 65280
ADVAL_1 = 65280
ADVAL_1 = 65280
ADVAL_1 = 65216
ADVAL_1 = 65216
ADVAL_1 = 65344
ADVAL_1 = 65344
ADVAL_1 = 65280
ADVAL_1 = 65344
ADVAL_1 = 65344
ADVAL_1 = 65280
ADVAL_1 = 65344

woodygjw
- 17th April 2005, 22:19
Mark,
I have the same problem using a 16f873. I know that this is not the right way, but it was a temporary thing that I did til I could research more, which I have not had time to do, but I think this may work for you:

loop:
ADCIN 0, adval1 ' Read AN0
' adcin 1, adval2 ' Read AN1
LET adval1 = adval1/64
'LET adval2 = adval2/64

if adval1 < 512 then
high PORTB.4
else
low PORTB.4
endif

serout2 PORTB.3,16572,["ADVAL_1 = ",dec adval1,13,10]
pause 100
goto loop
End

But there are pro's here that will show you the proper way:)

Greg

mister_e
- 17th April 2005, 22:26
oups, sorry, since a long time i didn't use this built-in ADCIN statement. Still prefer to read/write register myself.

BTW, what about now if you remove those PBP define and do something like


ADCON0=%11000001
ADCON1=%10001110

MUC
- 17th April 2005, 23:05
Thanks both of you. After looking closer at the ADCON registers, which I had done a few dozen times, I noticed I only had seven not eight bits. Steve, thank you for your last post. When I pasted it to my program it was obvious I had left out one bit in each ADCON register. I did have to leave the DEFINE for number of bits and sample time to get it to work. The code is now working and returns 1024 for 5V.

Regards,
Mark


DEFINE OSC 20

' Define ADCIN parameters
Define ADC_BITS 10 ' Set number of bits in result
Define ADC_SAMPLEUS 50 ' Set sampling time in uS

ADCON0 = %11000001
ADCON1 = %10000100 ' AN4-AN0 D,A,D,A,A right justify
TRISA.0 = 1
TRISA.1 = 1

adval1 var word
adval2 var word

clear
High PORTB.5 ' turn on run LED
low PORTB.4 ' low voltage LED
loop:
ADCIN 0, adval1 ' Read AN0
adcin 1, adval2 ' Read AN1

if adval1 < 512 then
high PORTB.4
else
low PORTB.4
endif

serout2 PORTB.3,16572,["ADVAL_1 = ",dec adval1," ADVAL_2 = ",dec adval2,13,10]
pause 100
goto loop
End

mister_e
- 18th April 2005, 15:13
MUC,

Great to know it's working now.

Have fun!

flotulopex
- 21st March 2008, 20:05
A few times ago, I had the same problem (16bits result instead of 10bits) as long I didn't notice my result was not RIGHT justified.

In fact, I wrongly assumed that the "DEFINE ADC_BITS 10" would handle this... but it doesn't.

Where can one see what exactly each PBP DEFINE statement does? Couldn't find this in the manual.

skimask
- 21st March 2008, 20:07
Where can one see what exactly each PBP DEFINE statement does? Couldn't find this in the manual.
You can see the RESULTS of a DEFINE in the .lst files, or you can manually scan thru the .lib's and find whichever particular DEFINE you need to find. It's a bit of a pain...

sougata
- 22nd March 2008, 18:30
Sorry if Vbulletin has already sent notification emails. No intentions biting some bytes on the server.

skimask
- 22nd March 2008, 18:31
Hi,
I never used the PBP ADC routines and used my own always but never got 1024 only 1023 ?
Well, that was almost 2 years ago. Maybe things worked differently back then :D

sougata
- 22nd March 2008, 18:36
Hi,

Skimask how can you be so fast replying.... I am always beaten out