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

Exit from long loop with interrupt?

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



Joined: 10 Apr 2006
Posts: 3
Location: North Carolina, USA

View user's profile Send private message

Exit from long loop with interrupt?
PostPosted: Mon Apr 10, 2006 5:40 pm     Reply with quote

Currently the program starts / stops the blinking pattern of the LEDs attached to the output pins. However, as written it can't stop within the loop, only between loops. How can I cause the loop to end after the interrupt? I know that I could set a flag in the interrupt and then check it between LED changes, but that doesn't seem to be an elegant method.

Code:

#include "D:\Data files\robot\BlinkLED\BlinkLED.h"

void setup();


boolean btnToggle = false;

#int_EXT
void EXT_isr() {
   output_low(PIN_A2);   // indicate that program is within ISR
   disable_interrupts(GLOBAL);
   if (btnToggle){
      btnToggle = false;
   }else{
      btnToggle = true;
   }
   delay_ms(50);
   clear_interrupt(INT_EXT);
   enable_interrupts(GLOBAL);
   output_high(PIN_A2);
}



void main() {
   setup();

   while(true){
      if(btnToggle){                         //change LED pattern
         output_toggle(PIN_B3);
         delay_ms(500);

         output_toggle(PIN_B3);
         output_toggle(PIN_B2);
         delay_ms(500);

         output_toggle(PIN_B2);
         output_toggle(PIN_B1);
         delay_ms(500);

         output_toggle(PIN_B1);
         output_toggle(PIN_B5);
         delay_ms(500);

         output_toggle(PIN_B5);
         delay_ms(500);
      }
   }
}

void setup(){
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(VREF_LOW|-2);
   ext_int_edge(H_TO_L);
   enable_interrupts(INT_EXT);
   enable_interrupts(GLOBAL);
   setup_oscillator(OSC_4MHZ);

   output_float(PIN_B0);
   output_high(PIN_B3);
   output_high(PIN_B2);
   output_high(PIN_B1);
   output_high(PIN_B5);
   output_high(PIN_A2);
}
kender



Joined: 09 Aug 2004
Posts: 768
Location: Silicon Valley

View user's profile Send private message Send e-mail Visit poster's website Yahoo Messenger

PostPosted: Mon Apr 10, 2006 8:00 pm     Reply with quote

Add more places where you test the flag, which you set in the ISR. For example:

Code:

while(true){
      if(btnToggle) goto endloop;                         //change LED pattern

      output_toggle(PIN_B3);
      delay_ms(500);

      if(btnToggle) goto endloop;

      output_toggle(PIN_B3);
      output_toggle(PIN_B2);
      delay_ms(500);

      if(btnToggle) goto endloop;

      output_toggle(PIN_B2);
      output_toggle(PIN_B1);
      delay_ms(500);

      if(btnToggle) goto endloop;

      output_toggle(PIN_B1);
      output_toggle(PIN_B5);
      delay_ms(500);

      if(btnToggle) goto endloop;

      output_toggle(PIN_B5);
      delay_ms(500);

// or you can also split up your delay routines like this
// instead of delay_ms(500);
for (i = 0; i < 5; ++i)
{
     delay_ms(100);
     if(btnToggle) goto endloop;
}

endloop:
}
asmallri



Joined: 12 Aug 2004
Posts: 1635
Location: Perth, Australia

View user's profile Send private message Send e-mail Visit poster's website

Re: Exit from long loop with interrupt?
PostPosted: Mon Apr 10, 2006 11:03 pm     Reply with quote

TekTrixter wrote:
Currently the program starts / stops the blinking pattern of the LEDs attached to the output pins. However, as written it can't stop within the loop, only between loops. How can I cause the loop to end after the interrupt? I know that I could set a flag in the interrupt and then check it between LED changes, but that doesn't seem to be an elegant method.


Using a flag is in the interrupt handler is elegant. I suggest the following:

    get rid of the disable interrupts in the interrupt handler unless there are other interrupt sources that you specifically want disabled.
    get rid of the enable_interrupts(global) in your interrupt handler - it is a sure way to crash the PIC.
    get rid of the clear_interrupt(INT_EXT) from the interrupt handler . It is not required the compiler does it automatically for you.
    get rid of the delay_ms from the interrupt handler. By putting this in the handler the compiler will add a disable interrupts into the mainline code whenever delay_ms is invoked which means you may lose interrupts.

    A method I use is to enable a timer in the interrupt handler - in your case one with 50ms timeout. You can then sit in the handler until the timeout expires - alternatively (the method I use) you can return immediately from the handler and in the mainline you can test if the timer is running (means an interrupt has occured and you are waiting for a timeout) then loop until the timer IF is set. You can then stop the timer, clear the flag and clear the output.

    Alternatively (or in addition) use a timer instead of delay_ms() in the mainline. In this case you would clear the TF flag and start the timer. You you then sit in a while loop such as

    Code:

         Ext_Intr_Processed_by_handler = false;
         while (!Some_Timer_TF & !Ext_Intr_Processed_by_handler)
                  // do nothing
                 ;
           // here if the timer expired or an interrupt was processed
           // do something else ....

_________________
Regards, Andrew

http://www.brushelectronics.com/software
Home of Ethernet, SD card and Encrypted Serial Bootloaders for PICs!!


Last edited by asmallri on Tue Apr 11, 2006 5:55 pm; edited 2 times in total
Humberto



Joined: 08 Sep 2003
Posts: 1215
Location: Buenos Aires, La Reina del Plata

View user's profile Send private message

PostPosted: Tue Apr 11, 2006 7:33 am     Reply with quote

Code:


//----------------------------------
#INT_EXT
void EXT_isr()
{
   if( btnToggle)
     { btnToggle = false; }
   else
     { btnToggle = true;  }
}

//-----------------------------------
void my_wait_loop(int times)
{   
   do
     {
      delay_ms(10);
     }while((--times) && (btnToggle));
}
//-----------------------------------

In main replace delay_ms(500) for my_wait_loop(n);
Code:

         output_toggle(PIN_B3);
         output_toggle(PIN_B2);
         my_wait_loop(50);

         output_toggle(PIN_B2);
         output_toggle(PIN_B1);
         my_wait_loop(50);
 



Humberto
Mark



Joined: 07 Sep 2003
Posts: 2838
Location: Atlanta, GA

View user's profile Send private message Send e-mail

PostPosted: Tue Apr 11, 2006 8:58 am     Reply with quote

Just to add upon what's already been posted
Code:

void my_wait_loop(int times)
{   
   do
     {
      delay_ms(10);
     }while((--times) && (btnToggle));
}

void main()
{
  int state;
  setup();

  while(true)
  {
    state = 0;
    while (btnToggle)
    {
      switch (state)
      {
        case 0:
          output_toggle(PIN_B3);
          break;
        case 1:
          output_toggle(PIN_B3);
          output_toggle(PIN_B2);
          break;
        case 3:
          output_toggle(PIN_B2);
          output_toggle(PIN_B1);
          break;
        case 4:
          output_toggle(PIN_B1);
          output_toggle(PIN_B5);
          break;
        case 5:
          output_toggle(PIN_B5);
          break;
        case 6:
          state = 0;
          continue;
      }
      state++
      my_wait_loop(50);
    }
  }
}
TekTrixter



Joined: 10 Apr 2006
Posts: 3
Location: North Carolina, USA

View user's profile Send private message

PostPosted: Wed Apr 19, 2006 10:26 am     Reply with quote

Thank you to everyone that replied. Mark's suggestion of a CASE is what I was origionally looking for (it avoids cut and pasting code). I also needed the interruptable delay as well (and didn't even know it!). I'd like to specificly thank asmallri for the list of corrections and hints.

I'm now working on a function for an interruptable delay using a timer interrupt and a break_delay flag.

Again, thank you to everyone that helped out.
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