|
|
View previous topic :: View next topic |
Author |
Message |
jdasari Guest
|
ADC on PIC16F877 |
Posted: Wed Apr 02, 2003 10:58 pm |
|
|
I'm trying to read the voltage feed into channel 4 of the ADC on port A and then print it to the LCD screen. For some reason the program seems to get stuck in the while loop and does not print the readings from the ADC onto the screen. I have the code below. Any help will be greatly appreciated.
int flag=0;
float bat_voltage;
lcd_init();
setup_adc_ports(ALL_ANALOG);
setup_adc(ADC_CLOCK_DIV_2);
set_tris_a(0xFF);
while (flag == 0)
{
set_adc_channel(4);
delay_us(100);
lcd_putc (" \f In the while loop \n");
delay_ms(10000);
bat_voltage=read_adc();
printf(lcd_putc,"bat_voltage=\%f", bat_voltage);
//lcd_putc(bat_voltage);
if(bat_voltage == 3)
{
lcd_putc (" \f Full Charge \n");
flag=1;
}
}
lcd_putc("\f Exiting \n");
}
___________________________
This message was ported from CCS's old forum
Original Post ID: 13335 |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
Re: ADC on PIC16F877 |
Posted: Thu Apr 03, 2003 1:15 am |
|
|
:=I'm trying to read the voltage feed into channel 4 of the ADC on port A and then print it to the LCD screen. For some reason the program seems to get stuck in the while loop and does not print the readings from the ADC onto the screen. I have the code below. Any help will be greatly appreciated.
---------------------------------------------------
I'm not at the company, so I can't test anything, but I can
make a few comments on your code.
:=
:= int flag=0;
The A/D converter returns an integer value. There's no reason
to make this next variable be a float. If you're using the
A/D in 8 bit mode, then make it be an int8. If you're using
the A/D in 10 bit mode (#device adc=10) then declare it to be
an int16.
:= float bat_voltage;
:= lcd_init();
:= setup_adc_ports(ALL_ANALOG);
:= setup_adc(ADC_CLOCK_DIV_2);
I would put this next line before the ADC setup lines above.
It would look cleaner that way (to me).
:= set_tris_a(0xFF);
:=
:= while (flag == 0)
:= {
:= set_adc_channel(4);
:= delay_us(100);
:= lcd_putc (" \f In the while loop \n");
This is a 10 second delay. That alone, could make the code
appear to be "locked up".
:= delay_ms(10000);
Here, you're putting the adc value, which will be either 8 or
16 bits, into a float. As I said, I'm not at the company, so
I can't confirm this, but I wouldn't do something like this.
It would not surprise me if the code crashed, with CCS, if
you did this. If you really want to return a float, you should
specifically cast the function so it returns a float.
ie.: bat_voltage = (float)read_adc();
But, the best thing to do, as I said above is to declare
bat_voltage as an int8 or int16. That's because read_adc()
only returns an 8 or 10 bit value.
:= bat_voltage=read_adc();
Then, you should change this next line so it displays an 8
or 16 bit integer. Ie., use \%u or \%lu instead of \%f.
:= printf(lcd_putc,"bat_voltage=\%f", bat_voltage);
:= //lcd_putc(bat_voltage);
This next line is very bad. You're testing for an exact value
which may never occur. You should test for "greater than or
equal to".
Also, are you assuming that the value read from the A/D is in
volts ? So you're trying to test for at least 3 volts ?
It doesn't return volts. If you're running the A/D in 8-bit
mode, it returns a value from 0 to 255. Assuming that your
reference voltage is +5v (Vdd), then 255 corresponds to +5v,
and 153 would be approximately 3.0 volts. So I think you
need to think about this some more.
:= if(bat_voltage == 3)
I think you probably want to do this:
<PRE>
if(bat_voltage >= 153)
or better yet, do this:
#define _3_VOLTS 153 // Put this line above main()
if(bat_voltage >= _3_VOLTS)
</PRE>
:= {
:= lcd_putc (" \f Full Charge \n");
:= flag=1;
:= }
:= }
:=
:= lcd_putc("\f Exiting \n");
Is this brace here, at the end of main() ? If so, you should
put a while(1); statement here, so the PIC does not go to sleep.
:=}
___________________________
This message was ported from CCS's old forum
Original Post ID: 13340 |
|
|
jdasari Guest
|
Re: ADC on PIC16F877 |
Posted: Fri Apr 04, 2003 1:09 pm |
|
|
Thanks much PCM. One quick question.
When I set the Vref using the set_vref(vrefhHigh | Value) function, how should I factor in the value which seems to be an intiger value from 0 - 15?
Regards
-dj
___________________________
This message was ported from CCS's old forum
Original Post ID: 13410 |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
Re: ADC on PIC16F877 |
Posted: Fri Apr 04, 2003 1:18 pm |
|
|
:=Thanks much PCM. One quick question.
:=When I set the Vref using the set_vref(vrefhHigh | Value) function, how should I factor in the value which seems to be an integer value from 0 - 15?
:=
----------------------------------------------------
I'm not sure what you mean by "factor in".
The 16F877 does not have a Vref module. So you can't use
that CCS function with the 16F877.
The 16F877A has one. But it's only for use with the Comparator
module in that chip. It's not used with the A/D.
With either of these two chips, if you want to use a Vref
other than Vdd, you have to supply it with an external circuit
and apply it to the appropriate Vref pin.
___________________________
This message was ported from CCS's old forum
Original Post ID: 13411 |
|
|
jdasari Guest
|
Re: ADC on PIC16F877 |
Posted: Tue Apr 08, 2003 11:36 pm |
|
|
Please bear with my beginners ignorance here.
Once I get the voltage reading using the read_adc( ) how can I convert that into the actual decimal voltage. i.e For e.x if I read 153 how can display that as 3 volts on the LCD? I have my code pasted below. Thanks much in advance.
#include <lcd.c>
#include <keybd.c>
void main()
{
int choice=1; int flag=0;
int8 bat_voltage;
float dig_voltage= 0;
lcd_init();
set_tris_a(0xFF);
setup_adc_ports(ALL_ANALOG);
setup_adc(ADC_CLOCK_DIV_32);
while (flag == 0)
{
set_adc_channel(1);
delay_us(100);
bat_voltage=read_adc();
printf(lcd_putc,"\f bat_voltage=\%u", bat_voltage);
if(bat_voltage >= 255)
{
lcd_putc (" \f Full Charge \n");
flag=1;
}
dig_voltage = (bat_voltage*5)/255;
printf(lcd_putc,"\n \%f", dig_voltage);
delay_ms(1000);
}
lcd_putc("\f Exiting \n");
while(1);
}
___________________________
This message was ported from CCS's old forum
Original Post ID: 13521 |
|
|
|
|
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
|