3

I wanted to know if it is possible to break a while loop and restart the code from a particular position without the use of an external reset button on the MCU reset pin.

Below is the while loop I would like to break when the "if" statement is true, I am using an LCD and would like to return to a particular part in my code where text is displayed (to imitate a home page).

As it is, when the "if" statement is true the while loop is broken and the code ends.

int main(void)
{
    /***************************************** BUTTON CONFIGURATION ********************************/

    DDRA &= ~((1<<PINA0) | (1<<PINA1) | (1<<PINA2) | (1<<PINA3));   // Config pins as inputs (ADC3 - Matching with ADMUX assignment below in ADC configuration)

    DDRC = 0xFF;        // Output pins for LEDs

    PORTA |= (1<< PINA0) | (1<<PINA1) | (1<<PINA2); // Three pins for three push buttons

    /****************************************** ADC CONFIGURATION **********************************/

    ADMUX |= (1<<MUX0) | (1<<MUX1) | (1<<REFS0);        // ADC3 and Internal voltage as reference voltage

    MCUCR &= ~((1<<ADTS2) | (1<<ADTS1) | (1<<ADTS0));   // Free running mode

    ADCSRA |= (1<<ADEN) | (1<<ADATE) | (1<<ADIE);   // ADC, Auto trigger source enable and start conversion

    sei();  // Enable global interrupts

    /***************************************** LCD CONFIGURATION ***********************************/

    LCD_Data_DDRB |= (1<<LCD_D7) | (1<<LCD_D6) | (1<<LCD_D5) | (1<<LCD_D4);     // Set output lines for lower 4 bits 

    LCD_Data_DDRD |= (1<<LCD_B3) | (1<<LCD_B2) | (1<<LCD_B1) | (1<<LCD_B0);     // Set output lines for upper 4 bits 

    LCD_Control_DDRB |= (1<<RS) | (1<<RW) | (1<<EN);                // Set RS, RW & EN output lines

    /******************************************** START CODE **************************************/

    LCD_Initialise();   // Run function to initialize the LCD

    LCD_startup();      // Run function which displays default start up text

    ADCSRA |= (1<<ADSC);    // Start conversion

    LCD_Send_Command(DISP_CL);

    while(1)
    {   

      if(Default > Final) 
      {
        LCD_Send_Command(DISP_CL);
        LCD_Send_Command(DISP_CS | LINE_1);
        LCD_Send_String(" text would go here"); 
        break;
      }

      else
      {
          ;
      }

    }

}

LoneCoder
  • 45
  • 6
  • 1
    @unwind has a safe solution to your problem. I am not familiar with the specifics of Atmel controllers, but I would assume that exiting the main function will result in reentry of the main function. This is what I saw with microchip controllers. Actually you can easily try that yourself. Toggle some pins at specific places and watch them with an oscilloscope. – jwsc Apr 22 '16 at 08:35
  • Thank you for comment I will look into this and give it a try! – LoneCoder Apr 22 '16 at 08:42

1 Answers1

5

This is slightly hard to understand, since you don't show the code you want to "restart".

Perhaps you can use another loop surrounding the one you show:

while(1)
{
  code_that_is_restarted();
  while(1)
  {
    if(Default > Final) /* Very bad variable names */
    {
      break;  /* Exits the inner loop only. */
    }
  }
}

The break; will exit the innermost loop only, so execution will continue in code_that_is_restarted();.

unwind
  • 391,730
  • 64
  • 469
  • 606
  • Thank you for your quick response, I will give this a try. I have also added a simplified version of my code just to show where I am trying to re-enter after breaking. – LoneCoder Apr 22 '16 at 08:42