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 trouble with the PIC 16F873
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
hanckmann



Joined: 16 Apr 2004
Posts: 9

View user's profile Send private message Visit poster's website

ADC trouble with the PIC 16F873
PostPosted: Thu May 06, 2004 3:28 am     Reply with quote

Hello,

I have some trouble reading the ADC. Below I copy-pasted some pieces of the code I use. When I read the ADC I always get the same values (always: 0, 64, 192). I do not understand. I red a lots of articles about this in the forum, but I do not see what I am doing wrong.
Please note:
- I did set the #device with adc=10
- I have to but back the ports to NO_ANALOGS because I have to share some ports
- The program compiles fine and all the drivers (like SetMux and SetResistor) are tested and are good
- I do wait at least 10 ms
- It goes into the ADC_TEST because I can read stuff

Code listing:
==================================================
Code:

Please review the code provided later in this topic !
It has the same problem, but is more easy to read !

IT DOES WORK NOW... PLEASE READ THE LAST POST(S)


==================================================
End of code listing

If anybody can help me solving my problem I would be very grateful.

Best regards

Patrick


Last edited by hanckmann on Fri May 07, 2004 5:17 am; edited 4 times in total
Haplo



Joined: 06 Sep 2003
Posts: 659
Location: Sydney, Australia

View user's profile Send private message

PostPosted: Thu May 06, 2004 4:24 am     Reply with quote

Just a few questions:

1. What is the value of SETPORTA? Are you setting the A/D pins as inputs?

2. What is the maximum frequency of the signal you are trying to convert? For a 4MHz crystal ADC_CLOCK_DIV_32 is too slow, You'd better use SETUP_ADC_PORTS(ADC_CLOCK_DIV_8);.

3. You said your ADC reads values like 0, 64 and 192. Do you mean the ADC itself, or the value of the variables adc1 and adc2? Since you have a division by 0x7F you shouldn't get anything higher than 8.
hanckmann



Joined: 16 Apr 2004
Posts: 9

View user's profile Send private message Visit poster's website

Answers
PostPosted: Thu May 06, 2004 4:39 am     Reply with quote

1. #DEFINE SETPORTA 0x0B //binary: 001011 RA0

2. I am measuring a DC power. It might change a bit, but at this moment not. (I will think of this for my fnal design)

3. I made an error in the post. The division by 0x7F was to check something else. This was not included in the piece of software which I was testing. Sorry for that (I changed in the source code listed above).

If you have more questions please let me know...

P
Haplo



Joined: 06 Sep 2003
Posts: 659
Location: Sydney, Australia

View user's profile Send private message

PostPosted: Thu May 06, 2004 4:44 am     Reply with quote

Two quick things:
You are setting RA0,RA1 and RA3 to analog. But you are using SET_ADC_CHANNEL(1); and SET_ADC_CHANNEL(2); which correspond to RA1 and RA2. Your RA2 is not even set as an analog pin, and according to the value of SETPORTA, it is set to output. Remember for RA0 and RA1 you have to use SET_ADC_CHANNEL(0); and SET_ADC_CHANNEL(1);.

Secondly, still your RA1 reading should be correct. Did you try the SETUP_ADC_PORTS(ADC_CLOCK_DIV_8); to see if it helps?
hanckmann



Joined: 16 Apr 2004
Posts: 9

View user's profile Send private message Visit poster's website

Changed, but nothing changes
PostPosted: Thu May 06, 2004 5:04 am     Reply with quote

Ok, I changed the program following your directions.
The output to the lcd did not change except that the values are now alway 32 or 160.
I don't know if you can do anything with those values, but ...

P
Haplo



Joined: 06 Sep 2003
Posts: 659
Location: Sydney, Australia

View user's profile Send private message

PostPosted: Thu May 06, 2004 5:14 am     Reply with quote

Well what are the DC voltages you are measuring? What values are you expecting to see on the LCD?
hanckmann



Joined: 16 Apr 2004
Posts: 9

View user's profile Send private message Visit poster's website

Expecting...
PostPosted: Thu May 06, 2004 5:48 am     Reply with quote

Well I expect to see a number between 0-1024 corresponding to the voltage which I can measure at the input of the AN0/AN1 to appear at the lcd screen.

The input is now connected to a powersupply (adjustable)
^- that was a mistake (it said not but it had to be now)
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu May 06, 2004 1:06 pm     Reply with quote

Quote:
I expect to see a number between 0-1024 corresponding to the
voltage which I can measure at the input of the AN0/AN1 to appear at the
lcd screen.


Quote:
When I read the ADC I always get the same values (always: 0, 64, 192). I do not understand


The fact that the bottom 6 bits are always 0 should be an important clue.
In the A/D section of the data sheet you will find a chart showing how
the A/D result can be left or right justified. Some versions of the CCS
compiler handle this automatically, depending on the setting of the
#device adc=xx statement, but your version may not have that feature.

To set the bit manually, see the last post in this thread.
http://www.ccsinfo.com/forum/viewtopic.php?t=2771&highlight=adfmbit

You didn't say what PIC you are using. The address shown for the
ADFM_BIT of 0x9F.7 will work for the 16F877, etc. If you have some
other PIC, you should check the data sheet to verify the address.
hanckmann



Joined: 16 Apr 2004
Posts: 9

View user's profile Send private message Visit poster's website

Tried but....
PostPosted: Fri May 07, 2004 2:31 am     Reply with quote

Ok I tried this:

Code:

   0x9F= 0x9F | 0x80;      // this sets the ADFM bit


but now i get this error message:
Error[61] MAIN.C 81 : LVALUE required

The PIC I use is the 16F873

What to do because i think you have a good point there...

The code I am using now is as follows:
Code:

#NOLIST            // Provided units
#INCLUDE   <16F873.h>
#INCLUDE   <stdlib.h>
#INCLUDE   <stdio.h>
#INCLUDE   <LAMdefines.c>      // All global defines (partly provided)
#LIST
#FUSES   HS,NOWDT,NOPROTECT,NOBROWNOUT,NOLVP
#USE    DELAY(CLOCK=4000000)
#USE    FAST_IO(A)
#USE   FAST_IO(B)
#USE    FAST_IO(C)
#NOLIST
#INCLUDE    <Button.c>      // Button driver (for 2 buttons, MODE and SET)
#INCLUDE    <LCD_c.c>      // Lcd driver --> This is NOT the standard lcd driver
#INCLUDE    <Multiplexer.c>      // Multiplexer driver
#INCLUDE    <Resistor.c>      // Digital potentiometer driver
// GENERAL UNITS
#LIST

void InitSystem(void)
// Initialize system
// pre:   -
// post:   System initialized; I/O and LCD are set
{
   // define inputs and outputs
   Set_Tris_A (SETPORTA);
   Set_Tris_B (SETPORTB);
   Set_Tris_C (SETPORTC);
   Disable_Interrupts(GLOBAL);
   SetMux(0);
   InitResistor();
   Lcd_init();
}

void main(void)
{
   int16 adc1, adc2;
   InitSystem();   
while(FOREVER)
{
   SETUP_PORT_A(RA0_RA1_RA3_ANALOG);
   SETUP_ADC_PORTS(ADC_CLOCK_DIV_8);
   0x9F= 0x9F | 0x80;      // this sets the ADFM bit // added sinds the last post
   SetResistor(1, AMP_A_12);      // Amplification chanal 1
   SetResistor(2, AMP_A_12);      // Amplification chanal 2
   SetResistor(3, OFFSET_A1X);
      SET_ADC_CHANNEL(0);
      delay_us(40);
      SetMux(0);
      adc1= READ_ADC();
      SET_ADC_CHANNEL(1);
      delay_us(10);
      SetMux(2);
      adc2= READ_ADC();
   lcd_clear();
   printf(lcd_putc,"X1: %ld\nX2: %ld", adc1, adc2);
   SETUP_PORT_A(NO_ANALOGS);
   Set_Tris_A (SETPORTA);
} // end of while(FOREVER)
} // end of main(void)


Last edited by hanckmann on Fri May 07, 2004 3:05 am; edited 1 time in total
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri May 07, 2004 2:50 am     Reply with quote

Quote:
Ok I tried this:
0x7F= 0x7F | 0x80;
but now i get this error message:
Error[61] MAIN.C 81 : LVALUE required

I suggest that you do it exactly the way it's shown in the linked post.
Haplo



Joined: 06 Sep 2003
Posts: 659
Location: Sydney, Australia

View user's profile Send private message

PostPosted: Fri May 07, 2004 2:51 am     Reply with quote

Quote:
0x7F= 0x7F | 0x80; // this sets the ADFM bit


That is not a correct C statement. The left hand side must be a variable.
hanckmann



Joined: 16 Apr 2004
Posts: 9

View user's profile Send private message Visit poster's website

ADFM bit set
PostPosted: Fri May 07, 2004 3:04 am     Reply with quote

I tried this as well:
ADFM_BIT = 1; // Right justify the A/D result
and this is a copy past from the other post. When I did this the following error occurs:
Error[12] MAIN.C 82 : Undefined identifier ADFM_BIT

Then i looked up the ADFM_BIT. It is the most significant bit of the ADCON1 register. This register is at address 0x9F. Here I thought that if I want to set the MSB in that register I would have to OR it with 0x80 (0b1000 0000).
This gave me the statement

0x9F = 0x9F | 0x80

(I first made the mistake by typing 0x7F, but the compiler result is the same:
Error[61] MAIN.C 81 : LVALUE required )

Then Haplo is ofcourse right, but how should I do this in this case ?
Haplo



Joined: 06 Sep 2003
Posts: 659
Location: Sydney, Australia

View user's profile Send private message

PostPosted: Fri May 07, 2004 3:14 am     Reply with quote

Try:

#bit ADFM_BIT=0x9F.7
ADFM_BIT=1;
hanckmann



Joined: 16 Apr 2004
Posts: 9

View user's profile Send private message Visit poster's website

Tried again, nothing changes again...
PostPosted: Fri May 07, 2004 3:45 am     Reply with quote

Ok, my program compiled succesfully now. It might be a part of my problem, but not everything. It is stil not working. At this moment it only reads a 0 (zero). At least, that is what my program prints on the LCD screen.

If somebody has some more ideas ???? Please ????
Haplo



Joined: 06 Sep 2003
Posts: 659
Location: Sydney, Australia

View user's profile Send private message

PostPosted: Fri May 07, 2004 4:18 am     Reply with quote

Tell us more about your circuit configuration.

Try these (all at the same time) and see if anything changes:

1.Change your oscillator fuse from HS to XT. For a 4MHz crystal you have to use XT, not HS. This may be the cause of the problem.
2.Change all FAST_IO lines to STANDARD_IO
3.Move the two fucntuion calls SETUP_PORT_A(RA0_RA1_RA3_ANALOG) and SETUP_ADC_PORTS(ADC_CLOCK_DIV_8) out of the while loop
4.Do not tweak the ADFM_BIT manually
5. Comment out the two SETUP_PORT_A(NO_ANALOGS) and Set_Tris_A (SETPORTA) lines at the end of the loop
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