CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

delay_ms disables global interrupt

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
gs



Joined: 22 Aug 2005
Posts: 30
Location: Ioannina - Greece

View user's profile Send private message Visit poster's website

delay_ms disables global interrupt
PostPosted: Tue Mar 10, 2009 5:14 pm     Reply with quote

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
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue Mar 10, 2009 5:48 pm     Reply with quote

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);

}
Ttelmah
Guest







PostPosted: Wed Mar 11, 2009 3:16 am     Reply with quote

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
gs



Joined: 22 Aug 2005
Posts: 30
Location: Ioannina - Greece

View user's profile Send private message Visit poster's website

PostPosted: Wed Mar 11, 2009 5:14 am     Reply with quote

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
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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