|
|
View previous topic :: View next topic |
Author |
Message |
Gizz
Joined: 15 Jun 2004 Posts: 21 Location: Nottingham UK
|
ADC on 16F877A (PCM 3.202) |
Posted: Mon Oct 11, 2004 3:34 pm |
|
|
Hi all.
Pulling my hair out here.
I have the following:
PCM compiler 3.202
16LF877A running on 3.4V and 9.8MHz
I note from this post
http://www.ccsinfo.com/forum/viewtopic.php?t=19616&highlight=adc+channel
that there is an issue with this version of the compiler and the ADC port setup.
What I am finding is that no matter what I set up in the clock speed or the ports for the ADC, and no matter how much of a delay I give it between channel select and reading, I get the same value on all channels that is present on channel 1.
How can I get hold of an update to the compiler? I bought it in June, it seems a bit carp to have to pay $100 for their error.
My code (snippets):
#include <16F877A.H>
#fuses HS, NOWDT, NOPROTECT, PUT, NOBROWNOUT, NOLVP
#use delay(clock=9831960)
#use rs232(baud=9600,xmit=PIN_C6,rcv=PIN_C7,ERRORS,STREAM=gprs)
#use rs232(baud=9600,xmit=PIN_D5,rcv=PIN_D4,ERRORS,STREAM=diagnostic)
#use i2c(Master, SDA=PIN_C4, SCL=PIN_C3) // Software i2c
#zero_ram
...
enable_interrupts(GLOBAL);
enable_interrupts(INT_RDA);
setup_timer_1(T1_INTERNAL);
enable_interrupts(INT_TIMER1);
setup_adc(ADC_CLOCK_DIV_64); // or internal, 32, etc
setup_adc_ports( AN0_AN1_AN2_AN3_AN4 ); // or any combination
...
if (PortNumber == MAINS_VOLTAGE_PORT)
{
set_adc_channel(1);
delay_ms(100);
read_adc(ADC_START_ONLY);
delay_ms(100);
value = read_adc(ADC_READ_ONLY);
fprintf(diagnostic, "Mains reads %lu\r\n", value);
}
else if (PortNumber == DEPTH_PORT)
{
set_adc_channel(5);
delay_ms(100);
read_adc(ADC_START_ONLY);
delay_ms(100);
value = read_adc(ADC_READ_ONLY);
fprintf(diagnostic, "Depth reads %lu\r\n", value);
}
Depth is always same as mains even though using scope and meter the volts at RA5 is 0.2 and the volts at RA1 goes from .6 to 1.2V (depending on unregulated supply volts).
Chip supply stays at 3.4V. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Oct 11, 2004 4:01 pm |
|
|
The first thing I would to find the problem is to simply your
program a lot.
1. Get rid of the "if" statements and just check the Depth channel.
2. Get rid of the fancy stuff with the ADC_START_ONLY, and
just use read_adc();
3. Shut down all interrupts.
In other words, the goal is to prove that you can make this
one thing work. So strip the program down until it only:
1. Setup the adc port.
2. Set the adc channel.
3. Read the adc.
4. Report the value read.
When you post your test program, you need to show your variable
declarations as well. For instance, what is "value" ? Is it a byte or
is it 16-bits ?
The issue may well be caused by the state of the justification bit
in one of the ADCON registers which controls whether it's left or
right justified.
If you make a small but complete test program that only tests
the ADC, as described above, then we can hammer the problem
until we find the answer. |
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Mon Oct 11, 2004 5:07 pm |
|
|
You also have the option of manipulating the registers yourself. So if the error is in their setup functions, it won't affect you. |
|
|
Gizz
Joined: 15 Jun 2004 Posts: 21 Location: Nottingham UK
|
|
Posted: Tue Oct 12, 2004 1:20 am |
|
|
Thanks, yes I know I should make it simpler: But I have already tried just using read_adc(), etc.
value is int16, and I use the ADC=10 switch on the #device .....
No matter, I will write a test prog that does just that one simple read.
But a quick question, if you will: If I want to set up the adc ports manually, how do I do this? Do I have to use assembler or is there a C variable declared for the ADC setup ports?
Thanks. |
|
|
Ttelmah Guest
|
|
Posted: Tue Oct 12, 2004 2:21 am |
|
|
Gizz wrote: | Thanks, yes I know I should make it simpler: But I have already tried just using read_adc(), etc.
value is int16, and I use the ADC=10 switch on the #device .....
No matter, I will write a test prog that does just that one simple read.
But a quick question, if you will: If I want to set up the adc ports manually, how do I do this? Do I have to use assembler or is there a C variable declared for the ADC setup ports?
Thanks. |
You use something like:
#byte ADCON0=0x1F
Then in your code, you can reference 'ADCON0', as a normal variable.
You can also declare the individual bits, with code like:
#bit ADON=ADCON0.0
and access 'ADON' as a variable.
In the thread 'why are some registers not defined in the devices.h file', Haplo, has just posted a pretty full list of all the declarations for the 16F87x, which makes it simple to access anything you want.
In the past, when I have had problems like yours, my 'general practice', has been to define either functions, or define macros, to equate closely with the CCS functions, with names like my_read_adc(). This makes it very easy to go 'back' to the CCS version, if latter the fault is fixed.
Best Wishes |
|
|
Gizz
Joined: 15 Jun 2004 Posts: 21 Location: Nottingham UK
|
|
Posted: Tue Oct 12, 2004 12:31 pm |
|
|
Thanks everyone, I have this just-about-working now.
It exhibited the same probs with a simple program.
I couldn't get the direct bit programming option to work (too impatient!)
Then I decided to earth out the other 5 unused ADC inputs (0, 3, 4, 6, 7) and lo! The 2 voltages (mains and batt) worked... but no depth.... turns out the depth ADC channel is ch 4 even though its wired to AN5 on the chip (yes I checked, several times!)
LOTS of crosstalk between the channels, and as AN5 was floating it appeared to be linked to AN1/AN2. Of course, when the unit has no internal battery fitted AN1 and AN2 are almost identical.
Ah well! Thanks once again! |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Oct 12, 2004 12:47 pm |
|
|
This is one of the reasons why I always push for a simple
test program. Once you're convinced that the error couldn't
possibly be in the simple program, then you're forced to take
a close look at everything else. By simplifying things, the
error stands out, and is easy to see. |
|
|
Ttelmah Guest
|
|
Posted: Tue Oct 12, 2004 2:40 pm |
|
|
Gizz wrote: | Thanks everyone, I have this just-about-working now.
It exhibited the same probs with a simple program.
I couldn't get the direct bit programming option to work (too impatient!)
Then I decided to earth out the other 5 unused ADC inputs (0, 3, 4, 6, 7) and lo! The 2 voltages (mains and batt) worked... but no depth.... turns out the depth ADC channel is ch 4 even though its wired to AN5 on the chip (yes I checked, several times!)
LOTS of crosstalk between the channels, and as AN5 was floating it appeared to be linked to AN1/AN2. Of course, when the unit has no internal battery fitted AN1 and AN2 are almost identical.
Ah well! Thanks once again! |
Is it possible, that you are being 'caught' by the fact that AN4, is _not_ on pin A4. The chip 'skips' this pin for the analog channels (because it is an open collector driver used for other things), so the pin that 'logically' would appear to be AN4, is not actually the AN4 input....
Just a thought.
Best Wishes |
|
|
Gizz
Joined: 15 Jun 2004 Posts: 21 Location: Nottingham UK
|
|
Posted: Wed Oct 27, 2004 6:23 am |
|
|
You are absolutely correct, Ttelmah, AN4 is on RA5.
Never mind, it all works now! Until the next crisis! |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|