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

200 ms Timer Interrupt?
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Izzy



Joined: 27 May 2007
Posts: 106

View user's profile Send private message

200 ms Timer Interrupt?
PostPosted: Mon Mar 31, 2008 7:43 pm     Reply with quote

Hello,

I have done enough search in this forum to find out a way to interrupt after every 200-250 ms but I havent been able to find an answer.

Please let me know a way to interrupt after every 200ms without interrupting multiple times and then calling the function

I am using 40Mhz cyrstal oscillator and a PIC18f4685

I think the max time I can get from Timer 1 is 52.xx ms

setup_timer_1(T1_INTERNAL | T1_DIV_BY_8)



40000000/4 = 10000000

1/10000000 = 0.1us

0.1 * 8 = 0.8us

0.8us * 65536 = 52.43ms Rolling Eyes





Thanks
w2drz



Joined: 27 Dec 2006
Posts: 55
Location: Western New York - USA

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

PostPosted: Mon Mar 31, 2008 9:53 pm     Reply with quote

Hi,

Look at timer 0,

#define RTCC_INTERNAL 0
#define RTCC_EXT_L_TO_H 32
#define RTCC_EXT_H_TO_L 48

#define RTCC_DIV_1 8
#define RTCC_DIV_2 0
#define RTCC_DIV_4 1
#define RTCC_DIV_8 2
#define RTCC_DIV_16 3
#define RTCC_DIV_32 4
#define RTCC_DIV_64 5
#define RTCC_DIV_128 6
#define RTCC_DIV_256 7

#define RTCC_OFF 0x80

#define RTCC_8_BIT 0x40

tom
Guest_7068
Guest







PostPosted: Mon Mar 31, 2008 9:57 pm     Reply with quote

Not happening.
You will need another counter inside your ISR to decide when to call the function:

Code:

int8 count = 4;

#INT_TIMER1
void timer1_isr(void)
{
   if (--count ==0)
       {
         call_my_function();
         count = 4; // Re-initialize count.
        }
}
w2drz



Joined: 27 Dec 2006
Posts: 55
Location: Western New York - USA

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

PostPosted: Mon Mar 31, 2008 10:52 pm     Reply with quote

I am using 40Mhz cyrstal oscillator and a PIC18f4685

I think the max time I can get from Timer 1 is 52.xx ms

setup_timer_1(T1_INTERNAL | T1_DIV_BY_8)



40000000/4 = 10000000

1/10000000 = 0.1us

0.1 * 8 = 0.8us

0.8us * 65536 = 52.43msHi,

To clarify what I suggest if you have timer 0 to use,

setup_timer_0(T0_INTERNAL | T0_DIV_BY_32)
// this will be (1) int for 52.4288 times 4 = 209.7152 ms

#INT_RTCC
void T0_isr ()
{
//set flag to be used for 209.7152 ms use
// if need exact 200 ms then it is more code for that use
}
Ttelmah
Guest







PostPosted: Tue Apr 01, 2008 2:21 am     Reply with quote

It depends what pins and timers are not used in your project.

Simplest, is probably just to implement a faster tick, and count.

You can get a value _slower_ than this (or faster), using Timer0.
Timer0, has a maximum division, of:
/4(fosc/4) /256(prescale) /65536
So you can give an interrupt just slightly slower than this, using a prescaler of 32, to give:
/4 /32 /65536 = /8388608 = 4.768* per second = 209.7mSec.

However if you 'must' have really close to 200mSec, then program a PWM output pin, and feed this back into the TOCKI input.
You can setup (say) the PWM to use the /16 prescale, and /121, which will generate a pulse at 40000000/(4*16*122)Hz = 5123Hz. Then use Timer0, in 8bit mode, with a /4 prescale from this, to give 5123/(4*256)Hz = 5.00288Hz
199.884mSec

Best Wishes
Matro
Guest







PostPosted: Tue Apr 01, 2008 4:58 am     Reply with quote

What you ask is not possible to do without external hardware...

Matro.
Izzy



Joined: 27 May 2007
Posts: 106

View user's profile Send private message

PostPosted: Tue Apr 01, 2008 6:40 am     Reply with quote

Hey guys,
Thanks a lot for help.


I thought Timer0 was a 8 bit timer. So its a 16 bit timer then?

No it does not need to be exact 200ms...something close should be good enough.

Code:
setup_timer_0(T0_INTERNAL | T0_DIV_BY_32)
// this will be (1) int for 52.4288 times 4 = 209.7152 ms



Few things I really want to check with you guys and make sure I am not following the wrong direction..

Can you guys briefly describe the difference between RTCC, Timer0, Timer 1 and Timer 2. What are their max prescaler? Howmany bit are those timers? What is the difference between Internal timer and external timer? Can we use internal oscilator as a clock for timers using setup_osc...?

I know most of these stuff but I think I am missing something. I would really appreciate if some one can briefly go over this so that I can make sure what I know is right or wrong.

Thanks in advance.
Ttelmah
Guest







PostPosted: Tue Apr 01, 2008 8:55 am     Reply with quote

Timer0, is an 8bit timer on the older chips. On the newer chips, it is programmable to be an 8bit, or 16bit timer. The constant 'RTCC_8_BIT', puts it back to 8bit mode for compatibility, otherwise it runs as a 16bit timer. :-)

Best Wishes
Ttelmah
Guest







PostPosted: Tue Apr 01, 2008 9:09 am     Reply with quote

For your other question, there is a application note on the MicroChip site, which describes the timers. Reading the data sheet is the main source of data.
The timers differ in where they can take their inputs 'from' (some allow external pins), how many bits they have, what prescalers they have, what postscalers they have, what resets them, and what they feed. So timer0 (which is also the RTCC - no difference, it is just that on the old chips it was referred to by this name), supports operating off Fosc/4, or the T0CKI pin. A prescaler of 1:1, to 1:256, in binary values only, and counts to 256, or 65536. It's only output, is the TMR0IF. Conversely, Timer2, can only come from Fosc/4, has just four prescale values, is only 8bit, but can be reset automatically at any count. It's output can be routed to run the SSP. It also has a postscaler before feeding the interrupt, making it the 'best' timer in general, for generating exact divisions, to feed an internal 'tick' interrupt. Timer1, supports it's own external oscillator, and can run the PWM (on later chips, Timer3 can also be used for this).

Best Wishes
inservi



Joined: 13 May 2007
Posts: 128

View user's profile Send private message

PostPosted: Wed Apr 02, 2008 3:50 am     Reply with quote

Hello Izzy.

For get interrupt for just 200mS, you can set your timer0 for interrupt every 209.7 as decribed Ttelmah. Then, simply set the timer0 counter to the right value (greater than 0) after each interrupt.

If 65536=209.7ms then :
9.7/200 = 0.485
65536*0.485 = 3178.4 = 9.7ms
65536-3178= 62358 = 200ms

Code:


#INT_RTCC
void T0_isr ()
  {
     set_timer0(62358) // for 200 ms
     ...
     your code
     ...
  }


void main() {
  ...
  setup_timer_0(T0_INTERNAL | T0_DIV_BY_32) = 209.7152 ms

  set_timer0(62358) // for 200ms

  enable_INTerrupts ( INT_TIMER0 );
  enable_INTerrupts ( global );
  ...





That is very simple.

Best regards,
dro
_________________
in médio virtus
Ttelmah
Guest







PostPosted: Wed Apr 02, 2008 4:53 am     Reply with quote

The problem is that it takes _time_ to get into the interrupt. Running off /256, it should be OK (provided there are no other interrupt driven devices), but normally this gives the problem of variable accuracy, as on occasions the clock will already have incremented when you reach the routine. So you end up not getting the required timing...

Best Wishes
inservi



Joined: 13 May 2007
Posts: 128

View user's profile Send private message

PostPosted: Wed Apr 02, 2008 6:01 am     Reply with quote

Hello Ttelmah,

You are right. But after little adjusting, the timing will be stable and reliable. correct ? I already used this method with success. I'm maybe not need the same precision ?

Best regards,
dro.
_________________
in médio virtus
Ttelmah
Guest







PostPosted: Wed Apr 02, 2008 10:29 am     Reply with quote

It can be made to work well, provided you don't have anything 'asynchronous' happening. If (for instance), you have interrupt driven serial comms, you will always run into the problem that if you are inside the serial interrupt, when the tick occurs, the amount of the time error will then be different from the normal occasions...

Best Wishes
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Wed Apr 02, 2008 10:47 am     Reply with quote

Try the technique below to correct for the unknown delay:
Code:
     set_timer0( get_timer0() + 62358 ) // for 200 ms
This has the advantage that it can correct for a variable delay like when another interrupt is comming in between. A minor problem in this solution is that if the timer increments in between the reading and writing of the timer value than you get an offset by 1 error.
inservi



Joined: 13 May 2007
Posts: 128

View user's profile Send private message

PostPosted: Wed Apr 02, 2008 11:12 am     Reply with quote

Thank you Ttelmah and ckielstra.
_________________
in médio virtus
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
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