|
|
View previous topic :: View next topic |
Author |
Message |
kk
Joined: 16 Nov 2010 Posts: 3
|
How to enable the interrupt after disable it |
Posted: Tue Nov 16, 2010 9:31 pm |
|
|
I am newbies to ccs c and have written the code like this below:
Code: |
enable_interrupts(int_rda);
enable_interrupts(global);
|
Then I have an isr to fetch the data say "mydata":
Code: |
while(1)
{
if (mydata=='A')
{ disable_interrupts(int_rda);
clear_interrupt(int_rda);
output_high(pin_a1);
delay_ms(500);
output_low(pin_a1);
delay_ms(500);
output_high(pin_a1);
delay_ms(500);
output_low(pin_a1);
delay_ms(500);
enable_interrupts(int_rda);
}
}
|
Then for first time, the pic can fetch mydata and then the interrupt is disabled and cannot be reenabled back.
Feel free to solve this problem, thanks. |
|
|
jds-pic
Joined: 17 Sep 2003 Posts: 205
|
|
|
kk
Joined: 16 Nov 2010 Posts: 3
|
|
Posted: Tue Nov 16, 2010 9:45 pm |
|
|
thanks ahh, for formatting my post so it become more readable. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19504
|
|
Posted: Wed Nov 17, 2010 3:01 am |
|
|
Now, on the interrupt.
A number of separate 'issues'. Some interrupts (INT_RB, INT_RDA, INT_TBE, etc.), have specific _hardware_ features that must be 'cleared', _before_ the interrupt itself can be cleared. In the case of INT_RDA, you can't just 'clear' the interrupt. If data is still sitting in the input buffer, it'll _set_ again immediately.
On INT_RDA, if more that two characters arrive, and are not handled (so, while INT_RDA is disabled), the UART receive component _will_ be disabled.
So, what is happening to you, is that while you have the interrupt disabled, characters are arriving, and the UART is then getting locked up.
Best solution:
Get rid of the delay code in the ISR. Do a search here on the 'mantra' 'keep interrupt handlers quick'.
Instead, when you receive 'A', set a 'flag'. Then in your 'main' code, have a routine that if it sees this flag set, does the outputs and the delay, then clears the flag again. This way the serial receive code can keep running.
You could also do the set/reset of A1, with a timer interrupt, as an alternative solution.
Add 'ERRORS' to your USE RS232 declaration. This adds code to the 'getc' routine, so that _if_ the UART is locked because data has been missed, will automatically clear it. This should be the default for every program using the hardware UART, _unless_ you are handling errors yourself.
Alternatively, you will need to add code to your routine, so that before re-enabling the interrupt, it checks for the UART being in the locked state, and if it is, clears the error (turns off the UART, then back on), reads any waiting characters, and only then enables the interrupt.
Best Wishes |
|
|
kk
Joined: 16 Nov 2010 Posts: 3
|
|
Posted: Wed Nov 17, 2010 5:10 am |
|
|
Wow, I don't even realize that...
I try with get rid of delay code, then it works.
That means, my coding has no "delay_ms" but using other parameter like set flag to turn on and off the led.
haha thanks for your valuable comment |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19504
|
|
Posted: Wed Nov 17, 2010 9:26 am |
|
|
Do a delay if you want, but out in the main code, not the interrupt.
However if you want the 'main' to be doing other things, then use an interrupt and timer.
delay_ms, in the interrupt, has another problem too, since it implies that all delays in the external code, _will_ have interrupts disabled during them. Pretty much ensuring interrupts _will_ be missed......
Best Wishes |
|
|
|
|
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
|