while(1) & Interrupts

Jul 22, 2018 at 12:15am
Hello everyone, I am using PIC micro controller to program a series of leds.
My question: is it possible to break out of while(1) loop in the animation with an interrupt? I know that this code doesn't do it, since all that happens after the interrupt flag is detected is the reset of the counter and animation selection is being incremented. I was thinking of stack pointers, but not sure if that will do the trick, any help?
Thanks in advance!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
// Interrupt routine
void interrupt ISR(void){
	if (TMR0IF && TMR0IE){		// (16MHz / (4 * 16 * 256))		[ 1.024 ms ]
		TMR0IF = 0;			// Clear Overflow Flag
		if (++counter > 29297){		// 19531 * 1.024 ms 		
			LED_Animation++;	// Change the animation at a fixed time interval
			counter = 0;			
		}
	}
}

// Superloop
	while(1){
		
		switch(LED_Animation) {
			
			case 0:		LED_Paparazzi();	break;
			case 1:		LED_FillnClear();	break;
			case 2:		LED_Slide();		break;
			case 3:		LED_MeetUp();		break;
			case 4:		LED_Chaser();		break;
			
			default:	LED_Animation = 0;	 
		}
	}

// Led Animation Function
void LED_Paparazzi(void){
	
	int j;
	
	while(1){
		j = (rand() % LED_SIZE);
		Switch_Led(j, ON);
		__delay_ms(50);
		Switch_Led(j, OFF);
		__delay_ms(100);	
	}
}
Last edited on Jul 22, 2018 at 7:17am
Jul 22, 2018 at 2:31am
Set a flag to quit from the loop in the handler for the interrupt, and in the condition for the while loop, check if the flag has been set.

For example, using standard signals:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include <csignal>
#include <iostream>
#include <chrono>
#include <thread>

static volatile std::sig_atomic_t interrupted = 0 ;

static void signal_handler( int signal )
{
  if( signal == SIGINT ) interrupted = 1 ;
  else
  {
      // ....
  }
}

int main()
{
  std::signal( SIGINT, signal_handler );

  std::cout << "press Ctrl+C to quit loop\n" << std::flush ;

  while( interrupted == 0 )
  {
      std::this_thread::sleep_for( std::chrono::milliseconds(200) ) ;
      std::cout << "loop\n" << std::flush ;
  }

  std::cout << "interrupted\n" ;
}
Jul 23, 2018 at 10:31am
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

static volatile char g_status = 0;

// Interrupt routine
void interrupt ISR(void){
	if (TMR0IF && TMR0IE){				
		TMR0IF = 0;					
		
		if (++counter > 4883){		
			LED_Animation++;		
			counter = 0; 
			g_status = 1;
		}
	}
}


// LED Animation
void LED_Paparazzi(void){
	
	int j;
	
	while(!g_status){
		
		Clear_Buffer();
		j = (rand() % LED_SIZE);
		Switch_LED(j, ON);
		delay(50);
		Switch_LED(j, OFF);
		delay(100);	
	}
}


So i attempted writing like this. The first break out of the while loop happens but it never goes to the next switch case (another animation). I need to clear g_status bit, but not sure how to do it... It does not work if I do it so in the interrupt routine anyway. Is this the good approach or should i try to do it as JLBorges suggested?
Last edited on Jul 23, 2018 at 10:32am
Jul 23, 2018 at 12:36pm
Anyone..
Jul 23, 2018 at 12:40pm
I need to clear g_status bit, but not sure how to do it.


g_status = 0;
Topic archived. No new replies allowed.