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

Setting up timer1

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



Joined: 12 Aug 2010
Posts: 119

View user's profile Send private message

Setting up timer1
PostPosted: Thu Nov 06, 2014 2:06 am     Reply with quote

Hi,

I am trying to set a timer to 1millisec delay , but not able to achieve it.
My code is as follows:

Code:


#include <18F2520.h>
#device ICD=TRUE ADC=10
#fuses HS, INTRC_IO,NOLVP,WDT128
#use delay (clock=8000000)

 
static int count = 0;

#INT_TIMER1
void timer1_isr()
{
   count++;
}
// Calculation 8Mhz divided internally by 4->2Mhz
// i.e 0.5 usec for one cycle
// Prescale =  1->1*0.5usec->0.5usec
// so for delay of 1msec 0.001/0.5u -> 2000 counts 65536-2000= 63536

void main()
{
   setup_timer_1(T1_INTERNAL | T1_DIV_BY_1);   
   set_timer1(63536); 

   enable_interrupts(INT_TIMER1);
   enable_interrupts(GLOBAL);
   while(true)
   {
      if(count>=500)
      {
         output_toggle(Pin_C0);
         count=0;
         set_timer1(63536);
      }
   }
}

and using 1msec I want to blink the LED after 500mSecs which is not happening.

kindly help!
sid
Mike Walne



Joined: 19 Feb 2004
Posts: 1785
Location: Boston Spa UK

View user's profile Send private message

PostPosted: Thu Nov 06, 2014 2:40 am     Reply with quote

Tell us what is happening.
Then we can make an informed guess at what your problem could be.

Mike

You could try modifying your ISR like this
Code:
{
   count++;
   set_timer1(63536);
}
Sid2286



Joined: 12 Aug 2010
Posts: 119

View user's profile Send private message

PostPosted: Thu Nov 06, 2014 2:51 am     Reply with quote

well, the timer is not running as expected, sometimes the LED toggles at 500msec and sometime it takes 10 secs.

I tried commenting INTRC_IO even that didnt help.

again I tried as what you suggested but even that is not helping.
Ttelmah



Joined: 11 Mar 2010
Posts: 19545

View user's profile Send private message

PostPosted: Thu Nov 06, 2014 3:32 am     Reply with quote

Start with how often the timer will tick.

8000000/(4*65536)= 30.5 * per second. Not 1mSec....

set_timer, only applies _once_. The other loops to the interrupt, all just count to 65536....

Then look at 'count'. You test for count being >500. What is the largest number that an int8 can hold?....

Don't fiddle directly with the timer count. Problems with this are enormous. What happens if the timer wraps between writing one byte and the other?. Remember also the timer _will_ have counted quite a few cycles before it arrives in the interrupt.
Remember also, just how much time an interrupt takes. If your timer was being called every 2000 counts, it'd be using over 4% of the processor's time. Lower frequency is better, especially since the clock you are using is not that accurate.

The below shows a 'trick' way, by just updating the MSB, to give 100 interrupts per second.

So:
Code:

#include <18F2520.h>
#device ICD=TRUE ADC=10
#fuses INTRC_IO,NOLVP,NOWDT //you were selecting two oscillators and
//the watchdog
#use delay (clock=8000000)
 
int count = 0; //a global doesn't need to be static. If it is, it is already
//initialised to 0.

#byte TIMER1_HIGH=getenv("SFR:TMR1H")
#BIT RD16 = getenv("BIT:RD16")

#INT_TIMER1
void timer1_isr()
{
   TIMER1_HIGH+=177;
   count++;
}
//Timer1, will now count 65536-(177*256) cycles = 20244
// Calculation 8Mhz divided internally by 4->2Mhz
// i.e 0.5 usec for one cycle
// Prescale =  1->1*0.5usec->0.5usec
// so counting to 20244 gives 98.8 interrupts per second
void main()
{
   setup_timer_1(T1_INTERNAL | T1_DIV_BY_1);   
   RD16=0;

   enable_interrupts(INT_TIMER1);
   enable_interrupts(GLOBAL);
   while(true)
   {
      if(count>=98) //remember you are counting from 0
      //This gives 99 counts, so 98.7:99 less than 0.2% error
      {
         count=0;
         output_toggle(Pin_C0);
      }
   }
}


If you must tick at 1mSec, then use timer2, that can be directly programmed to do this:

setup_timer_2(T2_DIV_BY_1,199,10);

Gives an interrupt every (199+1)*10 counts = 2000.
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