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

16F676 ADC-problem

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



Joined: 27 Aug 2006
Posts: 5

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

16F676 ADC-problem
PostPosted: Sun Aug 27, 2006 12:50 pm     Reply with quote

Hi,

My 16F676 seems to hang when calling the read_adc() function.
I've tried to change to other pins, different references etc.
Using CCS PCM 3.128
Can someone please help??

Code:


#include <16f676.h>
#device adc=10

#fuses INTRC_IO,NOWDT,NOBROWNOUT,NOPROTECT,PUT

#use delay(clock=4629167)
#use RS232(BAUD=9600, XMIT=PIN_C4, RCV=PIN_C5)

int16 result;

void main() {

setup_adc(ADC_CLOCK_INTERNAL);
setup_adc_ports(sAN3 | VSS_VDD);
set_adc_channel(3);
delay_us(10);

      while(TRUE) {
                   getc();
      result=read_adc();
      printf("AD=%x\n\r",result);
      
     }

}

Guest








PostPosted: Sun Aug 27, 2006 2:22 pm     Reply with quote

Hi,

Try adding 'NOLVP' to your fuses.

Jay
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun Aug 27, 2006 2:43 pm     Reply with quote

The 16F676 doesn't support LVP mode. The compiler won't accept the
NOLVP fuse. Here is what is wrong:
Quote:

My 16F676 seems to hang when calling the read_adc() function.
I've tried to change to other pins, different references etc.
Using CCS PCM 3.128

Your version of the compiler has got a lot of problems with the 16F676.

1. It doesn't call address 0x3FF at start-up so it can get the OSCCAL
value, which is stored at that address by Microchip. I notice you've got
a weird frequency in your #use delay() statement. It now becomes
clear why you've done that. You've tried to fix the delay code so it
will work with the unadjusted internal oscillator frequency.

2. The start-up code doesn't turn off the comparator. They're left in
the default state, which is "on". If you tried to use RA0, RA1, or RA2
this could cause problems.

3. The start-up code loads the ADCON0 register with 0x07. This is a
bug. It was supposed to load CMCON with 0x07, except they used
the wrong address.

4. The setup_adc(ADC_CLOCK_INTERNAL) function doesn't work
correctly. It should set the ADCS bits in ADCON1 to 011.
Instead, it sets them to 100, which selects OSC/4, not the internal
clock as intended. Also, this function is supposed to set the ADFM
bit = 1, to right-justify the result. It doesn't do this, so the result
will be left-justified.

5. The setup_adc_ports(sAN3 | VSS_VDD) function does work.
It sets up ANSEL correctly. They must have got lucky on this one.

6. The set_adc_channel(3) function doesn't work. It sets the A/D
to channel 6, instead of the intended channel 3. Also, it's using
RAM address 0x58 for a temporary register in this function.
Normally, CCS uses low ram for this, such as 0x20, 0x21, etc.
That alone, shows that this version has got major problems.

7. The read_adc() function doesn't work. It sets and polls bit 2 of the
ADCON0 register, when it should be bit 1, which is the GO/DONE bit.
This is what's causing your program to hang.


To fix all this, you would have to write some inline ASM code to fetch
the OSCCAL value from 0x3FF, and load the OSCCAL register.
You would have to write your own A/D functions.
danielkr



Joined: 27 Aug 2006
Posts: 5

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

PostPosted: Mon Aug 28, 2006 12:43 am     Reply with quote

I guess this explains why I've experienced so much problems. I guess I've learned a lesson too, never put too much trust to the compiler Smile
I'll try to write my own routines now.

Quote:


5. The setup_adc_ports(sAN3 | VSS_VDD) function does work.
It sets up ANSEL correctly. They must have got lucky on this one.



- Lucky with this one..... I get your point after looking at the datasheet Smile

Thank you for you help PCM!
danielkr



Joined: 27 Aug 2006
Posts: 5

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

read_adc
PostPosted: Mon Aug 28, 2006 2:47 pm     Reply with quote

I wrote my own read_adc. What do you guys think?

Code:

int16 my_read_adc(){
   bit_set(*0x1F,1);
   while(bit_test(*0x1F,1)){}
   return *0x9E+*0x1E*256;
}


Where 9E and 1E are the low and high result register.

Cheers!
Ttelmah
Guest







PostPosted: Mon Aug 28, 2006 3:02 pm     Reply with quote

Though it ought to work, why not use the byte/bit ability of the compiler?.
Code:

#byte ADRESL=0x9E
#byte ADRESH=0x1E
#bit ADGO=0x1F.1

int16 my_read_adc(void){
   ADGO=TRUE;
   while(ADGO) ;
   return(ADRESL+(ADRESH<<8));
}

I think this will make it easier to follow what is being done, especially if someone else has to look at the code sometime in the future.

Best Wishes
danielkr



Joined: 27 Aug 2006
Posts: 5

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

PostPosted: Tue Aug 29, 2006 1:40 pm     Reply with quote

A lot easier, and much prettier too..

I wonder if a <<8 and *256 is handled diffrent by the compiler?

Thanks Ttelmah Man!
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