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 support@ccsinfo.com

Problems with ADC in the PIC16F689

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



Joined: 20 Jul 2006
Posts: 29

View user's profile Send private message Send e-mail MSN Messenger

Problems with ADC in the PIC16F689
PostPosted: Sat Jul 28, 2007 9:49 pm     Reply with quote

Hi...
I have some problems with the A/D converter of the PIC 16F689. The code I am using is the following:


Code:
long int angulo;
void main()
{

   setup_adc_ports(sAN0|VSS_VDD);
   setup_adc(ADC_CLOCK_INTERNAL);
   set_adc_channel(0);
   setup_spi(SPI_SS_DISABLED);
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
   setup_timer_1(T1_DISABLED);
   setup_comparator(NC_NC_NC_NC);

delay_us(50);

while(true){
output_high(PIN_C5); //this is just a led pin.

angulo = 0;
angulo = read_adc(); //reads the adc and then stores the result in the variable angulo
delay_ms(100);
printf("%Lu",angulo); //prints the result through the serial port.
output_low(pin_c5);
}
}


The problem is that the ADC just doesn't seem to work. When I attach the pin AN0 to the VSS, the result should be 0 and it should be 1024 when the pin is attached to the VCC. But what I got was a 48 for when it is tied to the VSS and a crazy value in the other case.
Can you identify some problem with my code?
Any help would be of great value...
Thanks.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sat Jul 28, 2007 10:44 pm     Reply with quote

1. Do you have a debugger (ICD-U40, or ICD2) connected to your board
while you are running these tests ?

2. Post all the #fuse, #device, and #use statements for your program.

3. Post your compiler version.
Guest








Here it is.
PostPosted: Sun Jul 29, 2007 7:06 am     Reply with quote

Oh, sorry. My .h file is the following one.
Code:

#include <16F689.h>
#device adc=10
#FUSES NOWDT                    //No Watch Dog Timer
#FUSES XT                       //Crystal osc <= 4mhz
#FUSES NOPROTECT                //Code not protected from reading
#FUSES NOBROWNOUT               //No brownout reset
#FUSES NOMCLR                   //Master Clear pin used for I/O
#FUSES NOCPD                    //No EE protection
#FUSES NOPUT                    //No Power Up Timer
#FUSES NOIESO                   //Internal External Switch Over mode disabled
#FUSES NOFCMEN                  //Fail-safe clock monitor disabled
#use delay(clock=4000000)
#use rs232(baud=9600,parity=N,xmit=PIN_B7,rcv=PIN_B5,bits=8,stream=sensor)


My compiler's version is IDE, PCB, PCM, PCH 4.032.

I thought of some problem in the serial communication, but it is ok. I made the PIC transfer integer numbers to the other one in a FOR loop, and it worked perfectly. I don't know what may be happening.
otavio_fisica



Joined: 20 Jul 2006
Posts: 29

View user's profile Send private message Send e-mail MSN Messenger

PostPosted: Sun Jul 29, 2007 7:07 am     Reply with quote

I also do not have a debugger in my system.
I forgot logging in in the last reply. Sorry.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun Jul 29, 2007 5:29 pm     Reply with quote

Do you have a programmer attached to your board ? It uses the
AN0 pin.

I don't have a 16F689, but I do have a 16F690. I installed vs. 4.032
and compiled your program for the 16F690. I added a 500 ms delay
in your loop, because your loop was too fast.

I put a 5K trimpot on pin 19 (AN0), with the end terminals connected
to +5v and to Ground. I slowly turned the pot from one end to the
other, and it worked:
Quote:
1023
1023
1023
902
817
787
747
699
625
559
470
362
297
238
168
81
0
0


If the debugger (ICD2) is attached, then I get some missing codes.
That's because the AN0 pin is used by the debugger, and the debugger
loads down the pin. (I am using the ICD2 as a programmer).
Quote:
1023
1022
1022
<== Note missing codes
791
618
504
434
357
161
0
0
0


I suggest that you try a different pin which is not used by the debugger.
Try using AN4 instead, on pin 16. Make the changes shown in bold:
Quote:
setup_adc_ports(sAN4 | VSS_VDD);
setup_adc(ADC_CLOCK_INTERNAL);
set_adc_channel(4);
otavio_fisica



Joined: 20 Jul 2006
Posts: 29

View user's profile Send private message Send e-mail MSN Messenger

It still does not work
PostPosted: Mon Jul 30, 2007 7:13 am     Reply with quote

I do not have any ICD attached to my system. Yet I tried to change the pin, but the result was the same. After many tests, I tried the following code:

Code:
float media,final;
int16 i, angulo, parcial;
byte ser, a, saida;
int saidera;

while(true){
angulo = 0;
for (i=1;i<=3; i++){
   parcial = read_adc();
   angulo = angulo + parcial;
   delay_ms(200);
   }
media = angulo/3;
media = 255*media;
media = media/1023;
saidera=(int8)media;
putc(saidera);
}}


As you can see, I tried sending the value saidera. The calcullus with media were only tests. They will be different. I tried these ones just to change the scale to a int8 number that will be transmitted through the serial line. The calcullus will be different, but the result will still be a int8 number.
What I got was a 63 for when the analog channel is tied to the VCC and a 0 for when it is tied to the VSS. When it is tied to the system I want to measure, it works fine, but in this strange scale that goes from 0 to 63. According to my code, it should be from 0 to 255.
I tried many different variations of this code in the simulator, and everytime I implement the code in the hardware system, the result is the same.

I don't have any idea of what is happening.
otavio_fisica



Joined: 20 Jul 2006
Posts: 29

View user's profile Send private message Send e-mail MSN Messenger

PostPosted: Mon Jul 30, 2007 7:16 am     Reply with quote

Oh, I forgot... I tried to do it with that delay of 100us and then I changed to 200ms, for PCM said it was too fast. The result was the same for both the delays.
Just one more information.
Thanks for your help.
otavio_fisica



Joined: 20 Jul 2006
Posts: 29

View user's profile Send private message Send e-mail MSN Messenger

I tried this other code
PostPosted: Mon Jul 30, 2007 9:17 am     Reply with quote

I tried this other code:

Code:
while(true){
angulo = 0;
for (i=1;i<=3; i++){
   putc(i);
        delay_ms(200);
        parcial = read_adc();
        angulo = angulo + parcial;
   }
media = (float)4*angulo/3;
media = 255*media;
media = media/1023;
saidera=(int8)media;
putc(saidera);
}


The variables are of the same type of the ones of the last post.
I tried this because I think the problem was with the convertion of the variable media to a int8 type. I think the compiler was truncating the first two bits of the variable media (which uses only 10 bits). So I tried multipling the variable angulo by 4, so that the first two bits would be 0. During the convertion, the variable saidera would store the correct value of media.

I have difficulties on sending a in16 variable through the serial port to another pic. I mean, with the other pic, I can't get the result correctly to store it in a int16 variable. That's because I want to make all the calcullations before sending the value. If I could send directly the variable angulo, after the for loop, it would also solve my problem. I think it would be a better solution. But, if there's no other possibility, I think it's fine to do what I tried now. Do you agree? Any suggestion?
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Jul 30, 2007 12:00 pm     Reply with quote

Quote:
float media,final;
int16 i, angulo, parcial;
byte ser, a, saida;
int saidera;

while(true){
angulo = 0;
for (i=1;i<=3; i++){
parcial = read_adc();
angulo = angulo + parcial;
delay_ms(200);
}
media = angulo/3;
media = 255*media;
media = media/1023;
saidera=(int8)media;
putc(saidera);
}}


This code is too complicated for an initial test. Your purpose is to get
the A/D to give a good output. Use the test program that I posted
earlier. Don't do this complex math now.
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