![](templates/subSilver/images/CCSLogo.jpg) |
![CCS C Software and Maintenance Offers](templates/subSilver/images/forumAd6.jpg) |
View previous topic :: View next topic |
Author |
Message |
gs
Joined: 22 Aug 2005 Posts: 30 Location: Ioannina - Greece
|
delay_ms disables global interrupt |
Posted: Tue Mar 10, 2009 5:14 pm |
|
|
Hello, I have a simple test program that flashes a message on an lcd, and a timer1 interrupt that flashes a led. The message on the lcd is ok but the interrupt time does not work ok. The delay's used in the main program affect the timer1.
As I see from the .lst file, the compiler tests, and disables the global interrupts, when a delay_ms is compiled. Is there a way to avoid this?
In the CCS help file it says... If interrupts are enabled the time spent in an interrupt routine is not counted toward the time
I attach a part of the lst file.
Code: | .................... delay_ms(1000);
01EC: MOVLW 04
01ED: MOVWF @@2C
01EE: CLRF 29
01EF: BTFSC INTCON.GIE <------------------
01F0: BSF 29.7
01F1: BCF INTCON.GIE <--------------------
01F2: MOVLW FA
01F3: MOVWF ??65535
01F4: CALL @delay_ms1
01F5: BTFSC 29.7
01F6: BSF INTCON.GIE <---------------------------
01F7: DECFSZ @@2C,F
01F8: GOTO 1EE |
Is there something I do wrong?
I use version 4.084
the test program is this
Code: | #include <16F88.h>
#fuses XT,NOWDT,NOPUT,noPROTECT,NOBROWNOUT,MCLR,NOLVP,NOCPD,INTRC_IO
#use delay(clock=4000000)
#include <lcd420_keys_2.h>
int ticks=5;
/////////////////////////////////////////////
#int_timer1
void my_isr()
{
if(--ticks==0)
{
output_high(pin_a2);
delay_ms(10);
output_low(pin_a2);
ticks=5;
}
}
/////////////////////////////////////////////
void main()
{
delay_ms(200); //just wait a bit
lcd_init();
SETUP_TIMER_1(T1_INTERNAL|T1_DIV_BY_1);
enable_interrupts(INT_timer1);
enable_interrupts(GLOBAL);
do{
lcd_putc("\f Hello !!! ");
delay_ms(1000);
lcd_putc("\f");
delay_ms(1000);
}while(1);
} |
If I comment out the main's loop code as the following example, the interrupt works perfectly
Code: | do{
// lcd_putc("\f Hello !!! ");
// delay_ms(1000);
// lcd_putc("\f");
// delay_ms(1000);
}while(1); |
_________________ www.hlektronika.gr |
|
![](templates/subSilver/images/spacer.gif) |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Mar 10, 2009 5:48 pm |
|
|
The quick and dirty way to fix it, is just to give every section of your
code it's own instance of the delay routines. I'm not suggesting this
is the best way to solve your problem or anything. It will eliminate
the problem of the compiler disabling interrupts for delays. See the
lines added in bold below:
Quote: | #include <16F88.h>
#fuses XT,NOWDT,NOPUT,noPROTECT,NOBROWNOUT,MCLR,NOLVP,NOCPD,INTRC_IO
#use delay(clock=4000000)
#include <lcd420_keys_2.h>
int ticks=5;
/////////////////////////////////////////////
#use delay(clock=4000000)
#int_timer1
void my_isr()
{
if(--ticks==0)
{
output_high(pin_a2);
delay_ms(10);
output_low(pin_a2);
ticks=5;
}
}
/////////////////////////////////////////////
#use delay(clock=4000000)
void main()
{
delay_ms(200); //just wait a bit
lcd_init();
SETUP_TIMER_1(T1_INTERNAL|T1_DIV_BY_1);
enable_interrupts(INT_timer1);
enable_interrupts(GLOBAL);
do{
lcd_putc("\f Hello !!! ");
delay_ms(1000);
lcd_putc("\f");
delay_ms(1000);
}while(1);
} |
|
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah Guest
|
|
Posted: Wed Mar 11, 2009 3:16 am |
|
|
However, also worth doing a search here about this. Basically, putting delays inside the interrupt handler (except a few uSec, needed for timings to operate I/O lines etc.,), is generally uneccessary, and 'poor practice'. The compiler only disables interrupts in the external delays, _when delays are also used in the interrupt_.
For example, why not set your line high, and reprogram the interrupt to it triggers again in 10mSec, or program another interrupt to do this. Then get out of the ISR ASAP. This way your code can be getting on with other things, while waiting for the 10mSec....
Best Wishes |
|
![](templates/subSilver/images/spacer.gif) |
gs
Joined: 22 Aug 2005 Posts: 30 Location: Ioannina - Greece
|
|
Posted: Wed Mar 11, 2009 5:14 am |
|
|
Thank you both for the replies.
It was not a good idea to use the delay inside the interrupt, but I needed to see if the interrupt is working. I could use output_toggle instead. The real interrupt does not have a delay in it , so everything works fine now.
I understand the reason of the problem. Everyday I learn something new in here.
Thanks a lot _________________ www.hlektronika.gr |
|
![](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
|