CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

ADC on PIC16F877

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
jdasari
Guest







ADC on PIC16F877
PostPosted: Wed Apr 02, 2003 10:58 pm     Reply with quote

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

View user's profile Send private message

Re: ADC on PIC16F877
PostPosted: Thu Apr 03, 2003 1:15 am     Reply with quote

:=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
PostPosted: Fri Apr 04, 2003 1:09 pm     Reply with quote

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

View user's profile Send private message

Re: ADC on PIC16F877
PostPosted: Fri Apr 04, 2003 1:18 pm     Reply with quote

:=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
PostPosted: Tue Apr 08, 2003 11:36 pm     Reply with quote

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
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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