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

pic16f877a adc help
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
dxdxdx



Joined: 05 Jan 2011
Posts: 10

View user's profile Send private message

pic16f877a adc help
PostPosted: Wed Jan 05, 2011 9:48 am     Reply with quote

hi all, I'm new to pic. Currently I'm having an assignment to read an analog input (0~5V) at pin A0, so that different led light will be on for different case.
I need to separate the input into 5 case:
case 1: 0-1V = pin B0 on
case 2: 1-2V = pin B1 on
case 3: 2-3V = pin B2 on
case 4: 3-4V = pin B3 on
case 5: 4-5V = pin B4 on

I have tested with a simulator, but it is only pin B0 on, no matter what value I set as A0 input voltage. Please help me out with this, please point out my mistake I have made and make correction. Thanks alot.

Below is my code:
Code:

#include <16F877.h>
#device adc=8   
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=2000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, BRGH1OK)

void main(void)
{

long value;

set_tris_b(0b00000000);

setup_adc_ports( RA0_ANALOG );
setup_adc(ADC_CLOCK_INTERNAL);
set_adc_channel( 0 );
delay_us(10);

while( TRUE )
{
    value=read_adc();
    read_adc(ADC_START_ONLY);
    value=read_adc(ADC_READ_ONLY);
   
    if(0<value<=1)
    {
         output_high(PIN_B0);
    }
    else
    {
      if(1<value<=2)
      {
         output_high(PIN_B1);
      }
      else
      {
         if(2<value<=3)
         {
            output_high(PIN_B2);
         }
         else
         {
            if(3<value<=4)
            {
               output_high(PIN_B3);
            }
            else
            {
               output_high(PIN_B4);
            }
         }
      }
    }
}
}
newguy



Joined: 24 Jun 2004
Posts: 1907

View user's profile Send private message

PostPosted: Wed Jan 05, 2011 10:15 am     Reply with quote

Couple of things. The A/D converter returns a number, not a voltage. Since your converter is set to 8 bits, there are 256 different numbers possible from the A/D converter, which are in the range 0 - 255. The number you get depends on "how far up the ladder" your input voltage falls compared to the high and low reference voltages that the A/D converter uses. [Read more about the references and how to set up the A/D converter by the way.]

For an A/D converter that's been set up with a low reference voltage of Vss (0V) and a high reference of Vcc (I'll assume is 5V), and is in 8 bit mode, a 1V input will result in an A/D output number of:

Code:
1V (input to A/D) / (5V - 0V) = 0.2  (5V - 0V) is the difference between the high and low reference voltages

0.2 * 255 (max number the A/D will output) = 51.


Second, your tests aren't valid C. Do this instead:

Code:
if (value < 51) {
   output_high(PIN_B0);
   // you'll also have to output_low all the other pins to turn them off here
}
else if (value < 102) {
   output_high(PIN_B1);
   // see comment above about turning every other pin off
}
else if ... // hopefully you get the point
dxdxdx



Joined: 05 Jan 2011
Posts: 10

View user's profile Send private message

PostPosted: Wed Jan 05, 2011 10:44 am     Reply with quote

Hello newguy, thanks for replying. Now I have changed my code into this.
But it is still the same, the led is not on even if I set different input value.

Here is the print screen of my simulator:



Code:

#include <16F877.h>
#device adc=8   
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=2000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, BRGH1OK)

void main(void)
{
long value;

set_tris_b(0b00000000);

setup_adc_ports( RA0_ANALOG );
setup_adc(ADC_CLOCK_INTERNAL);
set_adc_channel( 0 );
delay_us(10);

while( TRUE )
{
    value=read_adc();
    read_adc(ADC_START_ONLY);
    value=read_adc(ADC_READ_ONLY);
   
    if(0<value<=51)
    {
         output_high(PIN_B0);
         output_low(PIN_B1);
         output_low(PIN_B2);
         output_low(PIN_B3);
         output_low(PIN_B4);
    }
    else
    {
      if(value<=102)
      {
         output_high(PIN_B1);
         output_low(PIN_B0);
         output_low(PIN_B2);
         output_low(PIN_B3);
         output_low(PIN_B4);
      }
      else
      {
         if(value<=153)
         {
            output_high(PIN_B2);
            output_low(PIN_B0);
            output_low(PIN_B1);
            output_low(PIN_B3);
            output_low(PIN_B4);
         }
         else
         {
            if(value<=204)
            {
               output_high(PIN_B3);
               output_low(PIN_B0);
               output_low(PIN_B1);
               output_low(PIN_B2);
               output_low(PIN_B4);
            }
            else
            {
               output_high(PIN_B4);
               output_low(PIN_B0);
               output_low(PIN_B1);
               output_low(PIN_B2);
               output_low(PIN_B3);
            }
         }
      }
    }
}
}
newguy



Joined: 24 Jun 2004
Posts: 1907

View user's profile Send private message

PostPosted: Wed Jan 05, 2011 11:17 am     Reply with quote

Once again - read the manual entry for "setup_adc()" and "setup_adc_ports()". Open "16F877.h" and look for the A/D converter section. Read it. Consult the datasheet for the 16F877 too.

And again,

Code:
if (0 < value <= 51) {
...
}


isn't valid C syntax.

Finally, don't trust a simulator. Ever
gpsmikey



Joined: 16 Nov 2010
Posts: 588
Location: Kirkland, WA

View user's profile Send private message

PostPosted: Wed Jan 05, 2011 11:51 am     Reply with quote

One of the first things to learn to do troubleshooting things is to have "test points" in the middle so you can check the intermediate results and figure out where things went wrong. In this case, try watching the output from the ADC and verify it is changing as the input changes as expected. Make sure it is in the range you expect - trying to fix the following code won't work if the input to the code is not valid. Make sure you have the ADC set up correctly and the values read by it are correct first then move on to the next part of the code.

mikey
_________________
mikey
-- you can't have too many gadgets or too much disk space !
old engineering saying: 1+1 = 3 for sufficiently large values of 1 or small values of 3
demonspells



Joined: 06 Jan 2011
Posts: 26

View user's profile Send private message Yahoo Messenger MSN Messenger

PostPosted: Thu Jan 06, 2011 8:10 am     Reply with quote

Check your clock delay, it says 2000000, if you're using a 20MHz crystal, you have to fix it.
temtronic



Joined: 01 Jul 2010
Posts: 9226
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Thu Jan 06, 2011 8:16 am     Reply with quote

Also, whenever you include 'use rs232(...) be sure to add the 'errors' option !
Rosmaninho



Joined: 16 Jan 2011
Posts: 23

View user's profile Send private message

PostPosted: Sun Jan 16, 2011 4:08 pm     Reply with quote

Hi, I'm new here, I have two questions, can you help me?

- In this code, at the beginning have #use rs232, we only need this if we use serial communications? It's correct?

- I'm using a 16F876. I have one bug in my configuration, I define Rb has output, but I can't set pin Rb3 high. I read the manual. I have to do something, but I don't know what.


Basic, my project is, had temperature in LM35, connect to ADC port. Then had the result to a display, or 2 Seven Segments LEDs or LCD. I want to control an extra output relay to control an heater.

Regards
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun Jan 16, 2011 9:03 pm     Reply with quote

Quote:
but I can't set pin Rb3 high.

Then make a test program where you only try to do one thing:
Set pin B3 high. Example:
Code:

#include <16F877.H>
#fuses XT, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP
#use delay(clock=4000000)

//==========================================
void main()
{

output_high(PIN_B3);

while(1);
}
 
Rosmaninho



Joined: 16 Jan 2011
Posts: 23

View user's profile Send private message

PostPosted: Mon Jan 17, 2011 4:54 am     Reply with quote

I will try later, but i guess it don't work...

The pin RB3, Also have the function PGM, the manual says:

"Low Voltage ICSP Programming (LVP) is enabled by default, which disables the RB3 I/O function. LVP
must be disabled to enable RB3 as an I/O pin and allow maximum compatibility to the other 28-pin and
40-pin mid-range devices."

so, i have to disable LVP, but I don't know how to do....
Ttelmah



Joined: 11 Mar 2010
Posts: 19513

View user's profile Send private message

PostPosted: Mon Jan 17, 2011 9:02 am     Reply with quote

You already are.
NOLVP in the fuses....
What you need to check is that your programmer is actually writing these. read back the fuses from a chip you have programmed.

Best Wishes
Rosmaninho



Joined: 16 Jan 2011
Posts: 23

View user's profile Send private message

PostPosted: Mon Jan 17, 2011 9:54 am     Reply with quote

Sorry... i'm new in pic programmer Smile

In my program i don't have the order.... NOLVP Smile


I'll try again, nut, i guess it works properly Smile

Later i tell you Smile
gpsmikey



Joined: 16 Nov 2010
Posts: 588
Location: Kirkland, WA

View user's profile Send private message

PostPosted: Mon Jan 17, 2011 11:36 am     Reply with quote

What programmer are you using to program your parts?

Does it verify the "burned" part after programming ?

mikey
_________________
mikey
-- you can't have too many gadgets or too much disk space !
old engineering saying: 1+1 = 3 for sufficiently large values of 1 or small values of 3
Rosmaninho



Joined: 16 Jan 2011
Posts: 23

View user's profile Send private message

PostPosted: Mon Jan 17, 2011 12:07 pm     Reply with quote

I have this programmer:
http://cgi.ebay.com/ws/eBayISAPI.dll?ViewItem&item=260693779794&ssPageName=STRK:MEWNX:IT
gpsmikey



Joined: 16 Nov 2010
Posts: 588
Location: Kirkland, WA

View user's profile Send private message

PostPosted: Mon Jan 17, 2011 12:38 pm     Reply with quote

OK, it looks like it will verify the programming as well as allow you to view the fuses (with the "Fuses" button in the screenshot).

mikey
_________________
mikey
-- you can't have too many gadgets or too much disk space !
old engineering saying: 1+1 = 3 for sufficiently large values of 1 or small values of 3
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
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