![](templates/subSilver/images/CCSLogo.jpg) |
![CCS C Software and Maintenance Offers](templates/subSilver/images/forumAd6.jpg) |
View previous topic :: View next topic |
Author |
Message |
ccmcca
Joined: 08 Oct 2005 Posts: 13
|
WHY NEVER STOPS?? |
Posted: Sat May 06, 2006 8:31 pm |
|
|
#include "mainbalanza.h"
#int_RDA
RDA_isr()
{
printf("-INTERRUPT-");
delay_ms(1000);
}
void main()
{
ini();
delay_ms(10);
printf("------------------------------------\n\r");
printf("Running...\n\r");
printf("------------------------------------\n\r");
while(1)
delay_ms(1000);
}
Hello! My problem is that this code is doing this
------------------------------------
Running...
------------------------------------
-INTERRUPT--INTERRUPT--INTERRUPT--INTERRUPT--INTERRUPT--INTERRUPT--INTERRUPT--IN
TERRUPT--INTERRUPT--INTERRUPT--INTERRUPT--INTERRUPT--INTERRUPT--INTERRUPT--INTER
RUPT--INTERRUPT--INTERRUPT--INTERRUPT--INTERRUPT--INTERRUPT--INTERRUPT--INTERRUP
T--INTERRUPT--INTERRUPT--INTERRUPT--INTERRUPT--INTERRUPT-
And never stop...
I have to clean the interrupt or something? |
|
![](templates/subSilver/images/spacer.gif) |
rberek
Joined: 10 Jan 2005 Posts: 207 Location: Ottawa, Canada
|
|
Posted: Sat May 06, 2006 8:57 pm |
|
|
Yes, you have to clear the interrupt or else you will re-enter the ISR as soon as you exit it. Using a getc() inside the ISR will clear the interrupt.
I'm also assuming that the delay_ms(1000) inside the ISR is for debugging purposes only. |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah Guest
|
|
Posted: Sun May 07, 2006 3:17 am |
|
|
Actually, let's just 'clear this up'. Several people refer to 'clearing the interrupt', but this is _not_ what reading the character does!.
Basically, interrupts have a 'multi layer' hardware structure. There is a hardware 'event', which triggers the interrupt, and then the interrupt 'flag', set by this event. Now the interrupt handler _itself_, 'clears' the interrupt flag (CCS do this for you, unless you specify the interrupt with 'noclear'). However unless the character is read, the buffer is left 'full', and this will automatically 'set' the flag again, as soon as it is cleared.
What 'clearing' you have to do, varies with different interrupts. So (for instance), the 'INT0' interrupt, has it's 'hardware event', triggered only by the 'edge' of the incoming signal (rather than by a level). On this, once you clear the interrupt flag, nothing else is needed, and the interrupt will only trigger when the next active 'edge' is seen. Since this is done for you by CCS, no 'clearing' is apparently needed. However the serial 'receive' interrupt, and the 'port B change' interrupt, are both 'static' events, and will keep re-triggering, till the 'source' of the event is cleared (reading port B, or reading the incoming character).
So for the serial receive interrupt, _two_ things have to be cleared. First the 'source' (reading the character), and then the interrupt flag as well (but this is done for you).
There is also a third situation, the 'serial transmit' interrupt. On this, if you have no more data to send, the transmit buffer will remain empty, and the interrupt will keep re-triggering. Hence this if one of the few interrupts, where you must disable the interrupt itself inside the handler, when you have no more data to send.
Best Wishes |
|
![](templates/subSilver/images/spacer.gif) |
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Sun May 07, 2006 9:43 am |
|
|
Ttelmah wrote: | Actually, let's just 'clear this up'. Several people refer to 'clearing the interrupt', but this is _not_ what reading the character does!.
Basically, interrupts have a 'multi layer' hardware structure. There is a hardware 'event', which triggers the interrupt, and then the interrupt 'flag', set by this event. Now the interrupt handler _itself_, 'clears' the interrupt flag (CCS do this for you, unless you specify the interrupt with 'noclear'). However unless the character is read, the buffer is left 'full', and this will automatically 'set' the flag again, as soon as it is cleared.
What 'clearing' you have to do, varies with different interrupts. So (for instance), the 'INT0' interrupt, has it's 'hardware event', triggered only by the 'edge' of the incoming signal (rather than by a level). On this, once you clear the interrupt flag, nothing else is needed, and the interrupt will only trigger when the next active 'edge' is seen. Since this is done for you by CCS, no 'clearing' is apparently needed. However the serial 'receive' interrupt, and the 'port B change' interrupt, are both 'static' events, and will keep re-triggering, till the 'source' of the event is cleared (reading port B, or reading the incoming character).
So for the serial receive interrupt, _two_ things have to be cleared. First the 'source' (reading the character), and then the interrupt flag as well (but this is done for you).
There is also a third situation, the 'serial transmit' interrupt. On this, if you have no more data to send, the transmit buffer will remain empty, and the interrupt will keep re-triggering. Hence this if one of the few interrupts, where you must disable the interrupt itself inside the handler, when you have no more data to send.
Best Wishes |
Not exactly true. The UART interrupt flag bits are read only and cleared by hardware. From the manual:
Quote: |
The actual interrupt can be enabled/disabled by setting/clearing enable bit RCIE (PIE1<5>). Flag bit RCIF is a read only bit, which is cleared by the hardware. It is cleared when the RCREG register has been read and is empty. |
and for the transmit:
Quote: |
Once the TXREG register transfers the data to the TSR register (occurs in one TCY), the TXREG register is empty and flag bit TXIF (PIR1<4>) is set. This interrupt can be enabled/disabled by setting/clearing enable bit TXIE
( PIE1<4>). Flag bit TXIF will be set, regardless of the state of enable bit TXIE and cannot be cleared in software. It will reset only when new data is loaded into the TXREG register.
|
I've also seen some people say that the UART is 3 levels deep. This is not quite true. You cannot receive 3 complete bytes. You can receive 2 bytes while a 3rd byte is being received.
Quote: |
The RCREG is a double buffered register (i.e., it is a two deep FIFO). It
is possible for two bytes of data to be received and transferred to the RCREG FIFO and a third byte to begin shifting to the RSR register. On the detection of the STOP bit of the third byte, if the RCREG register is still full, the overrun error bit OERR (RCSTA<1>) will be set. The word in the RSR will be lost.
|
|
|
![](templates/subSilver/images/spacer.gif) |
|
|
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
|