Kirk Humphries

Timer interrupts

Discussion created by Kirk Humphries Employee on Jan 31, 2006

This message contains an entire topic ported from a separate forum. The original message and all replies are in this single message. We have seeded this new forum with selected information that we expect will be of value to you as you search for answers to your questions.

 

Posted: Mon Jul 18, 2005  1:20 pm

 

Can u tell me how to clear timer interrupt flags if you have two timers running ?

 

Do you have to write

 

TFLG1 = 0x01

or

TFLG1 |= 0x01

to clear Timer1 flag

 

and

 

TFLG1 = 0x02

or

TFLG1 |= 0x02

to clear Timer2 flag

 

in the isr ???

 

Thx for help

 


 

Posted: Mon Jul 18, 2005  1:30 pm

 

The assignment operations are almost right. TFLG1 is write-1-to-clear, so you must do the following:

 

TFLG1 = 0x01; /* To clear C0F (channel 0 flag) */

TFLG1 = 0x02; /* To clear C1F (channel 1 flag) */

TFLG1 = 0x04; /* To clear C2F (channel 2 flag) */

/* etc... */

 

Using the |= operator will cause lost interrupts. Imagine, for example, that both the channel 0 and channel 1 flags are set when the channel 0 handler is entered. Then TFLG1 will be 0x03. The operation "TFLG1 |= 0x01" would set TFLG1 to (0x03 | 0x01), which is 0x03. Writing that 0x03 will then reset *both* timer flags. The channel 1 interrupt handler will never get called, because its flag is already cleared! Thus, the |= operator is incorrect. The correct way to clear the flag is a simple assignment of the correct bit, not an |= operation.

 


 

Posted: Sat Jul 23, 2005  12:42 pm

 

Thx for your answer. I was busy and couldn´t reply earlier

 

Two more questions:

 

a) About those assembler commands:

_asm ("sei"); // disable interrupts

_asm ("cli"); // enable interrupts

 

Does the "sei" call block the jump into the individual isr, keeping the interrupts in a kind of buffer alive if they occur, or are interrupts between the call of "sei" and "cli" completly off and lost (not recorded)

 

b) Is the same principle to clear an interrupt flag of a timer valid for a port interrupt?

 

For example:

@interrupt void PIrq(void)

{

if (PIFP & 0x01)

{

PIFP |= 0x01;

P1Handler();

}

if (PIFP & 0x01)

{

PIFP |= 0x02;

P2Handler();

}

}

 

if PIFP is set with 0x03, will the reset of 0x01 clear both flags this way, too, and thus no jump into p2handler ?

 

Best regards

 


 

Posted: Wed Jul 27, 2005  8:47 am

 

See answers below:

 

Hope this helps,

 

>Thx for your answer. I was busy and couldn´t reply earlier

>

 

>Two more questions:

>

 

>a) About those assembler commands:

>_asm ("sei"); // disable interrupts

>_asm ("cli"); // enable interrupts

>

 

> Does the "sei" call block the jump into the individual isr, keeping the

> interrupts in a kind of buffer alive if they occur, or are interrupts

> between the call of "sei" and "cli" completly off and lost (not recorded)

 

The individual pending interrupts are "remembered" in the individual flag bit. Thus, as long as the individual flag for the specific interrupt has not been cleared, the interrupt is only temporarily disabled when the CCR I bit is set, and once the I bit becomes cleared again, it can be processed. (In other words, it is not lost).

 

You should also note that the interrupt processing mechanism automatically sets the CCR I bit when an interrupt service routine is started, and automatically pulls the old CCR register including the I bit value from the stack to the CCR register when the interrupt service routine is completed. This mechanism is in order to temporarily disable new interrupts while already servicing another interrupt, and when one interrupt processing is completed (when the RTI instruction is met), allow again processing more interrupts if there are any.

 

If there is a need to process other interrupts while already servicing one interrupt, the specific interrupt service routine can include the assembler "cli" instruction to enable processing other pending interrupts. The "sei" instruction should be included only after clearing the individual flag that caused the specific interrupt, in order to avoid starting many interrupt service routine for only one interrupt.

 

 

>b) Is the same principle to clear an interrupt flag of a timer valid for

>a port interrupt?

>

 

>For example:

>@interrupt void PIrq(void)

>{

>if (PIFP & 0x01)

>{

> PIFP |= 0x01;

> P1Handler();

>}

>if (PIFP & 0x01)

>{

> PIFP |= 0x02;

> P2Handler();

>}

>}

>

 

>if PIFP is set with 0x03, will the reset of 0x01 clear both flags

>this way, too, and thus no jump into p2handler ?

 

In this described method you may actually loose interrupts completely. The way to clear the individual interrupt flag is using:

 

PIFP = 0x02;

PIFP = 0x01;

 

and not:

 

PIFP |= 0x02;

PIFP |= 0x01;

Outcomes