Search code examples
cembeddedatmel8051

How to terminate the nested loop


Here I want to break out of a nested loop. I am using break statements to do so. The code is breaking out of the for loops but can't get out of the infinite while loop. I want to go to another function called resetClock() when the condition is true. I have tried every possible solution return, goto and break and still I am facing the same problem.

 #define MUX_PORT  P3
 #define enable_int{EA=1;}
 #define disable_int{EA=0;}

 void timer0() interrupt 1 {
     TL0 = 0x33;
     TH0 = 0xF5;
     MUX_PORT = 0x00;
     dig1 = dig2 = dig3 = dig4 = 0;
     DATA_PORT = 0x00;
     if (dig_disp > 4)
         dig_disp = 0;
     dig_disp++;

     switch (dig_disp) {
     case 1:
         dig1 = 1;
         MUX_PORT = seg_hex[sec0];
         break;
     case 2:
         dig2 = 1;
         MUX_PORT = seg_hex[sec1];
         break;
     case 3:
         dig3 = 1;
         MUX_PORT = seg_hex[min0];
         break;
     case 4:
         dig4 = 1;
         MUX_PORT = seg_hex[min1];
         break;
     }
 }

 void msDelay() {
     unsigned int i;
     for (i = 0; i <= 8; i++) {
         TMOD = 0x10;
         TH1 = 0x4B;
         TL1 = 0xFD;
         TR1 = 1;
         while (TF1 == 0);
         TR1 = 0;
         TF1 = 0;
     }
 }

 void start_Clock() {
     unsigned int loop_break = 0;
     TMOD = 0x01;
     TH0 = 0xF5;
     TL0 = 0x33; //63293
     IE = 0x82;
     TR0 = 1;
     while (SW_SHIFT == 1) {
         for (min1 = 0; min1 < 6; min1++) {
             for (min0 = 0; min0 <= 9; min0++) {
                 for (sec1 = 0; sec1 < 6; sec1++) {
                     for (sec0 = 0; sec0 <= 9; sec0++) {
                         msDelay();
                         if (SW_SHIFT == 0) {
                             loop_break = 1;
                             disable_int;
                             MUX_PORT = 0xFF;
                             dig1 = dig2 = dig3 = dig4 = 0;
                             break;
                         }
                         if (min0 == 2 && min1 == 1) {
                             min0 = 1;
                             min1 = 0;
                             sec0 = 0;
                             sec1 = 0;
                             continue;
                         }
                     }
                     if (loop_break == 1) break;
                 }
                 if (loop_break == 1) break;
             }
             if (loop_break == 1) break;
         }
         if (loop_break == 1) {
             resetClock();
         }
     }
 }

 void main() {
     unsigned int i, j;
     sec0 = sec1 = min0 = min1 = 0;

     SW_SET = 1;
     SW_SHIFT = 1;

     for (i = 0; i <= 250; i++)
         for (j = 0; j <= 1257; j++);

     start_Clock();
 }

 void resetClock() {
     unsigned int i, j, k, l;
     i = j = k = l = 0;
     SW_SHIFT = 1;
     SW_SET = 1;

     if (SW_SHIFT == 0) {
         dig_disp++;
         if (dig_disp > 3)
             dig_disp = 0;
     }
     switch (dig_disp) {
     case 0:
         while (SW_SET == 0) {
             dig1 = 1;
             i++;
             sec0 = i;
             MUX_PORT = seg_hex[sec0];
             if (i == 9)
                 i = 0;
         }
         break;

     case 1:
         while (SW_SET == 0) {
             dig2 = 1;
             j++;
             sec1 = j;
             MUX_PORT = seg_hex[sec1];
             if (j == 5)
                 j = 0;
         }
         break;

     case 2:
         while (SW_SET == 0) {
             dig3 = 1;
             k++;
             min0 = k;
             MUX_PORT = seg_hex[min0];
             if (k == 9)
                 k = 0;
         }
         break;

     case 3:
         while (SW_SET == 0) {
             dig4 = 1;
             l++;
             min1 = l;
             MUX_PORT = seg_hex[min1];
             if (l == 1)
                 l = 0;
         }
         break;
     }
 }

Solution

  • The correct way to write the code, in what I believe is the most readable way, would be to use functions and returns:

    void start_Clock() {
         unsigned int loop_break = 0;
         TMOD = 0x01;
         TH0 = 0xF5;
         TL0 = 0x33; //63293
         IE = 0x82;
         TR0 = 1;
    
         delay(); // give this some meaningful function name
    
         resetClock();
     }
    
    void delay (void)
    {
      while (SW_SHIFT == 1) {
        for (min1 = 0; min1 < 6; min1++) {
          for (min0 = 0; min0 <= 9; min0++) {
            for (sec1 = 0; sec1 < 6; sec1++) {
              for (sec0 = 0; sec0 <= 9; sec0++) {
                msDelay();
    
                if (SW_SHIFT == 0) {
                  disable_int; // NOTE: this looks fishy, likely bug
                  MUX_PORT = 0xFF;
                  dig1 = dig2 = dig3 = dig4 = 0;
                  return ;
                }
    
                if (min0 == 2 && min1 == 1) {
                  min0 = 1;
                  min1 = 0;
                  sec0 = 0;
                  sec1 = 0;
                }
    
              } // for (sec0 = 0; sec0 <= 9; sec0++)
            } // for (sec1 = 0; sec1 < 6; sec1++)
          } // for (min0 = 0; min0 <= 9; min0++)
        } // for (min1 = 0; min1 < 6; min1++) 
      } // while (SW_SHIFT == 1)
    }