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;