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

Problem with Timer. Please help

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



Joined: 03 May 2004
Posts: 8

View user's profile Send private message

Problem with Timer. Please help
PostPosted: Mon May 03, 2004 3:38 pm     Reply with quote

Here I am trying to finish the timing equipment for a local car club by friday, and my timer is acting up. I know it is some silly thing, but I cannot see what I am doing wrong.

All I am trying to do is to count the milliseconds using Timer1. Frequency of my crystal is 40Mhz. I am putting out a square wave too, in order to see how whats going on.

Code:


#int_timer1         
void timer1_isr()   
{
   counter++ ;
   if(flag)
   { output_low(PIN_B7);
     flag=0;
   }
   else
   { output_high(PIN_B7);
     flag=1;
   }
 
   set_timer1(1250);     
}

//- from main ----------

   counter=0;                 // ms counter

   setup_timer_1(T1_INTERNAL);
   set_timer1(1250);
   enable_interrupts(INT_TIMER1);
   
   while(input(SW1)==1){}

   enable_interrupts(GLOBAL);
   
   while(input(SW2)==1){}

//-- and then it displays the counter ---



I am getting around 6ms timeout right now, with those numbers. Weird thing is, if I try to change the count value with set_timer1 nothing changes :( .

Please help us have neat timers for racing Smile

Thanks,
Vlad
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon May 03, 2004 3:54 pm     Reply with quote

Quote:
Frequency of my crystal is 40Mhz.

Please verify whether you are attempting to use a 40 MHz crystal, or
are you really using a 10 MHz crystal with the 4x PLL oscillator mode ?
Also,

1. What PIC are you using ?
2. Please post your #fuses statement.
3. Also post your #use delay statement.
Vlad



Joined: 03 May 2004
Posts: 8

View user's profile Send private message

PostPosted: Mon May 03, 2004 10:31 pm     Reply with quote

1. PIC16F877A
2. I did not specify any fuses
3. #use delay(clock=40000000)

I am pretty sure it is 40Mhz because that is what it says on the crystal oscillator.
Haplo



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

View user's profile Send private message

PostPosted: Mon May 03, 2004 10:55 pm     Reply with quote

On PIC16 series you can not have a crystal faster than 20MHz. That's the maximum device speed.
Even on PIC18s you can not have a 40MHz crystal. If you want to operate at 40Mhz, you have to use a 10MHz crystal and activate the 4X PLL oscillator.

And it is always a good idea to specify the fuses. The NOLVP fuse at least, unless you are using low voltage programming.
rwyoung



Joined: 12 Nov 2003
Posts: 563
Location: Lawrence, KS USA

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

PostPosted: Tue May 04, 2004 8:20 am     Reply with quote

The PIC16F877A can't use a crystal faster than 20MHz. Your crystal might really be a 4MHz. I've seen some 4MHz cases marked as 4.0 and maybe the decimal point isn't too clear or just looks like dirt to your eyes Shocked

Check the oscillator operation with an oscilloscope (100MHz bandwith at least) and x10 probe (so you don't load down the pins so much they oscillator stops).

And like Halpo said, use the #fuse statement. I think that statement has caused more problems for people because they skipped it or misunderstood what the settings should be.
_________________
Rob Young
The Screw-Up Fairy may just visit you but he has crashed on my couch for the last month!
Vlad



Joined: 03 May 2004
Posts: 8

View user's profile Send private message

PostPosted: Tue May 04, 2004 8:35 am     Reply with quote

Thanks guys. That must be it... From what I recall on one of the boards from Microchip, you can select between the internal and external clock (crystal). Is that correct ?

Anyway, I am curious why would changing the timer overflow with set_timer1(N) not change the time between the interrupts ?

Thanks for the help,
Vlad
Vlad



Joined: 03 May 2004
Posts: 8

View user's profile Send private message

PostPosted: Tue May 04, 2004 8:43 am     Reply with quote

I just looked at the crystal, and its clearly 40MHz. I got this board from a friend who was using it for PIC18 chips, so it might as well be too fast for my PIC16. I guess I will see if he has slower crystal.
Vlad



Joined: 03 May 2004
Posts: 8

View user's profile Send private message

PostPosted: Tue May 04, 2004 9:14 am     Reply with quote

Put the 4MHz crystal in, but still no change with different overflows... I am going to try timer0, just in case.
Vlad



Joined: 03 May 2004
Posts: 8

View user's profile Send private message

PostPosted: Tue May 04, 2004 9:50 am     Reply with quote

Same problem with Timer0.

Code:

#include <16F877A.h>
#device ICD=TRUE
#device adc=8
#use delay(clock=4000000)
#include "math.h"
#fuses NOWDT,NOPROTECT,NOLVP
#use delay(clock=4000000)

//--- from main ---

setup_adc_ports(NO_ANALOGS);
   setup_adc(ADC_OFF);
   setup_psp(PSP_DISABLED);
   setup_spi(FALSE);

   setup_counters(RTCC_INTERNAL,RTCC_DIV_1);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);

   //-------------

   delay_ms(30);
   LCD_Init();

   //-------------

   LCD_Data();
   LCD_Setup_Digits();
   counter=0;                 // ms counter

   setup_timer_0(T1_EXTERNAL | T1_DIV_BY_1);
   set_timer0(2);
   enable_interrupts(INT_TIMER0);

   while(input(SW1)==1){}

   enable_interrupts(GLOBAL);

   while(input(SW2)==1){}
//---------

#int_timer0
void timer0_isr()
{
   counter++ ;
   if(flag)
   { output_low(PIN_B7);
     flag=0;
   }
   else
   { output_high(PIN_B7);
     flag=1;
   }

   set_timer0(2);
}

Ttelmah
Guest







PostPosted: Tue May 04, 2004 10:47 am     Reply with quote

General comment.
You _will not_ get accuracy, setting a timer to a value inside an ISR. Unfortunately, it takes time to get to the end of the ISR routine, and the time taken, depends on the path taken through the ISR. Hence when you set the timer to a value, you will generate timing errors. You really must leave the timer to free-run, and handle the timing 'tweaks' by adjusting the counter, rather than the timer value.
Either choose a cystal value, that gives a precise division to mSec steps in the interrupt, or accept that the steps will not be in mSec, but use a counter that increments using a binary multiple of the division factor required, and then scale the result to display mSec. The error from this will be small, and will be repeatable, so won't matter for a timing application.
You don't show your declaration of 'counter'. Remember this will have to be a long, and probably an int32, and will need to be printed as such.
Remember you need to disable the interrupt as soon as the falling edge is seen on the switch, or the code will keep counting, which can lead to 'silly' numbers if it changes between digits being displayed.
mSec accuracy, is 'pushing it'. You can do this with a 40MHz crystal, but at a slower cyrstal rate, the time taken in the interrupt itself will easily be _large_ relative to this sort of timing accuracy. Personally, I'd aim for 1/100th second, rather than mSec counting (this is all that is required for most professional racing...).

Best Wishes
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