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

Setup_timer_0(); with Constants and Variables

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



Joined: 09 Sep 2003
Posts: 183
Location: Somewhere under water in the Great Lakes

View user's profile Send private message

Setup_timer_0(); with Constants and Variables
PostPosted: Tue Mar 18, 2008 8:45 am     Reply with quote

I stumbled across an interesting "feature" of the compiler last night (actually this morning in the wee hours) and I thought I might see if anyone else has encountered this. I need to measure the frequency of a fairly slow signal. It can range from around 1/2Hz to more than 10Hz. Looking at the data sheet for the 18F8722, I decided to use Timer 0 and its prescalers. It appeared to fit perfectly, but here's my mistake. I tried to be clever and create a function that adjusted the prescaler if the timed value was less than some minimum to maintain resolution or greater than some maximum to avoid possible overflow. Silly me, I looked in the header file and found that the prescale values started with 8 for x1 then 0 for x2, 1 for x4, etc. up to 7 for x256. Cool, I just incremented the value and or'd it with RTCC_INTERNAL and used that as the parameter for setup_timer_0();.

Wrong!!!

It appears that the compiler looks at the predefined constant RTCC_INTERNAL and sets the control register with different value than the actual defined constant. RTCC_INTERNAL is defined as 0 but when the compiler sees this in the setup function is uses 0x80!!!! If there are any parameters other than those defined in device header file, 18F8722.h, it uses the defined value, 0, and or's this with the other parameters. This results in the timer being turned off. Nice!

Curiously, RTCC_OFF is defined as 0x80, which if used directly would enable the timer!?!?

Here's the listing from a test program. The first setup call was created by the Wizard with the RTCC internal box checked and the 0.4usec button selected. This should use the x1 prescaler. Unfortunately, if you don't or in a prescaler value, the default is 0 which yields a x2 prescaler.

The 2nd, 3rd, and 4th use the predefined constants and setup the timer correctly.

The 5th and 6th use a variable to set the parameter. The 6th uses the predefined constants to set the value of the variable. Neither of these setup the timer correctly: it will be disabled.

Code:


....................    setup_timer_0(RTCC_INTERNAL);
00046:  MOVLW  80
00048:  MOVWF  FD5
....................    setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
0004A:  MOVLW  88
0004C:  MOVWF  FD5
....................    setup_timer_0(RTCC_INTERNAL|RTCC_DIV_2);
0004E:  MOVLW  80
00050:  MOVWF  FD5
....................    setup_timer_0(RTCC_INTERNAL|RTCC_DIV_8);
00052:  MOVLW  82
00054:  MOVWF  FD5
....................    t0setup = 0x02;
00056:  MOVLW  02
00058:  MOVWF  05
....................    setup_timer_0(RTCC_INTERNAL|t0setup);
0005A:  MOVFF  05,FD5
....................    t0setup = RTCC_INTERNAL|RTCC_DIV_8;
0005E:  MOVLW  02
00060:  MOVWF  05
....................    setup_timer_0(t0setup);
00062:  MOVFF  05,FD5

nurquhar



Joined: 05 Aug 2006
Posts: 147
Location: Redditch, UK

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

PostPosted: Mon Apr 07, 2008 3:19 am     Reply with quote

I have just encounter this problem too !!! Shocked I am using PCH 3.249 with an 18F67J10.

This line runs the timer0 in 8bit mode :
Code:
setup_timer_0(RTCC_INTERNAL|RTCC_8_BIT|RTCC_DIV_32);


This line does not start the timer running, ie it does not set the enable bit (bit7) of T0CON.
Code:
unsigned int div ;
div = RTCC_INTERNAL | RTCC_8_BIT | RTCC_DIV_32 ;
setup_timer_0(div);


However the apparent fix required to make it work is to specifcaly include something to set bit7. ie :-
Code:
unsigned int div ;
div = 0x80 | RTCC_INTERNAL | RTCC_8_BIT | RTCC_DIV_32 ;
setup_timer_0(div);
Ttelmah
Guest







PostPosted: Mon Apr 07, 2008 4:06 am     Reply with quote

This is quite common!.
What CCS do, is XOR bit 7, if the value is a constant, but _not_ if it is a variable. I think the XOR, was a 'kludge' introduced when the newer bits were added to some timers, to 'retain compatibility' with the older constants already in use....
It happens on several of the latter register settings.

Best Wishes
RLScott



Joined: 10 Jul 2007
Posts: 430

View user's profile Send private message

Re: Setup_timer_0(); with Constants and Variables
PostPosted: Mon Apr 07, 2008 5:00 am     Reply with quote

This is another example of why it is often better to ignore CCS library functions and write to the SFRs yourself. Then you know for sure what is going on. The chip documentation for Timer 0 SFRs is simple enough that it does not need a layer of compiler junk to isolate you from it.

Robert Scott
Real-Time Specialties
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