title: Slight Delay After Returning from Interrupt
body: <p>I've written a small program that uses a button on an STM32 Discovery board to act as a counter in either Binary/Decimal/Hexadecimal mode (screen cycles through the 3 options and once pressed, counts up to 16 for each press before resetting to cycling through options).</p>
  
  <p>I'm encountering one small "bug" (read, not really) that has me a little confused. If I count up in Decimal/Hexadecimal, it returns to cycling through the options immediately but if I have counted up in Binary it takes ~1sec or so before doing so (a noticeable delay).</p>
  
  <pre><code>int main(void)
  {
      RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6, ENABLE);
      lcd_init();
      button_init();
  
      while (1)
      {
          while (!counting) {
              standard_output();
          }
      }
  
  }
  
  void standard_output(void) {
      state = 0;
      lcd_command(0x01);
      delay_microsec(2000);
      lcd_putstring("Binary");
      for (i=0; i&lt;40; i++) delay_microsec(50000);     // keep display for 2 secs
      if (counting) return;                           // if we have pressed the button, want to exit this loop
      state = 1;
      lcd_command(0x01);
      delay_microsec(2000);
      lcd_putstring("Decimal");
      for (i=0; i&lt;40; i++) delay_microsec(50000);     // keep display for 2 secs
      if (counting) return;                           // if we have pressed the button, want to exit this loop
      state = 2;
      lcd_command(0x01);
      delay_microsec(2000);
      lcd_putstring("Hexadecimal");
      for (i=0; i&lt;40; i++) delay_microsec(50000);     // keep display for 2 secs
      if (counting) return;                           // if we have pressed the button, want to exit this loop
  
  }
  
  void EXTI0_IRQHandler(void) {
      if (EXTI_GetITStatus(EXTI_Line0) != RESET) {
          if (!stillBouncing) {                               // a button press is only registered if stillBouncing == 0
              if (!counting) {                                // if we weren't already counting, a valid button press means we are now
                  counting = 1;
                  count = 0;                                  // starting count from 0
              }
              else {
                  count++;
              }
              if (count &lt; 16) {
                  lcd_command(0x01);
                  delay_microsec(2000);
                  format_int(count);
              }
              else {
                  counting = 0;                               // we are no longer counting if count &gt;= 16
              }
          }
          stillBouncing = 10;                                 // every time a button press is registered, we set this to 10
          while (stillBouncing &gt; 0) {                         // and check that it hasn't been pressed for 10 consecutive 1000microsec intervals
              if (!delay_millisec_or_user_pushed(1000)) {
                  stillBouncing--;
              }
          }
      }
      EXTI_ClearITPendingBit(EXTI_Line0);
  }
  
  void format_int(unsigned int n) {
      if (state == 0) {                                       // if we selected binary
          for (i=0;i&lt;4;++i) {
              num[i] = (n &gt;&gt; i) &amp; 1;                          // generate array of bit values for the 4 least significant bits
          }
          i = 4;
          while (i&gt;0) {
              i--;
              lcd_putint(num[i]);                             // put ints from array to lcd in reverse order to display correctly
          }
      }
      else if (state == 1) {                                  // if we selected decimal
          lcd_putint(n);                                      // lcd_putint is enough for decimal
      }
      else {                                                  // if we selected hex
          snprintf(hex, 4, "%x", n);                          // format string such that integer is represented as hex in string
          lcd_putstring(hex);                                 // put string to lcd
      }
  }
  
  int delay_millisec_or_user_pushed(unsigned int n)
  {
      delay_microsec(n);
      if (!GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0)) {
          return 0;
      }
      return 1;
  }
  </code></pre>
  
  <p>I really have no idea why it is doing this and have played around with it now but still unable to figure it out. It's fine as is but I would like to know <em>why</em> it is doing this.</p>