Electronic – Problem on NVIC STM32F100

arminterruptsstm32

I am using STM32VL discovery board(STM32f100rb6)..
I wrote following code for NVIC:

void Interrupt_Init(void)
{
    __enable_irq();
    /*Core Base(NVIC)*/

    //set priority to 0
    //NVIC->IP[6] &= ~((uint32_t)0xff00);

    //Activate Interrupts
    NVIC->ISER[0] |= BIT6;

    //Enable Pending BIT for Interrupt 6
    NVIC->ISPR[0] |= BIT6;
    lcd_writechar('1');
} 

and

int main(void)
{
Interrupt_Init();
    while (1)
    {

    }
}
void EXTI0_IRQHandler(void)
{
    //NVIC->ICPR[0] |= BIT6;

    lcd_writechar('2');
}

as you see under Interrupt_Init() I user NVIC->ISPR[0] |= BIT6; phrase to soft-enable exti0-IRQ. so void EXTI0_IRQHandler(void) subroutine must executed and I got '2' on LCD. but as NVIC->ISPR[0] |= BIT6; execute next line(lcd_writechar('1');) never runs.. but when I commented (NVIC->ISPR[0] |= BIT6;) I got '1' on LCD… whats going on??

Update:

I look further into "startup_stm32f10x_md_vl.s" file in my project as
startup file:

.section  .text.Default_Handler,"ax",%progbits
Default_Handler:
Infinite_Loop:
  b  Infinite_Loop
  .size  Default_Handler, .-Default_Handler

and:

g_pfnVectors:
  .word  _estack
  .word  Reset_Handler
  .word  NMI_Handler
  .word  HardFault_Handler
  .word  MemManage_Handler
  .word  BusFault_Handler
  .word  UsageFault_Handler
  .word  0
  .word  0
  .word  0
  .word  0
  .word  SVC_Handler
  .word  DebugMon_Handler
  .word  0
  .word  PendSV_Handler
  .word  SysTick_Handler
  .word  WWDG_IRQHandler
  .word  PVD_IRQHandler
  .word  TAMPER_IRQHandler
  .word  RTC_IRQHandler
  .word  FLASH_IRQHandler
  .word  RCC_IRQHandler
  .word  EXTI0_IRQHandler
...

and:

.weak  EXTI0_IRQHandler
.thumb_set EXTI0_IRQHandler,Default_Handler

It seems that "EXTI0_IRQHandler" always equal to "Default_Handler" in
my projects so it cause infinite loop as we define above.

I think this part:

void EXTI0_IRQHandler(void)
{
  NVIC->ICPR[0] |= BIT6;

  lcd_writechar('2');
}

never influences the "EXTI0_IRQHandler" definition. why?

Update:

Is there any way to jump to
EXTI0_IRQHandler without implementing anything in peripheral?? Like asm("B
0x58")? my purpose is to be sure from core configurations then work
on peripheral configurations ?

Update:

I nearly found problem but needs help to fix it.. after many
examination and using debug features I found this piece of code is
faulty:

    void EXTI0_IRQHandler()
    {
      lcd_writechar('2');
      LED_ON();
      NVIC->ICPR[0] |= BIT6;
    }

in detail lcd_writechar('2'); cause to issue because inside function
I am using delay() function.This is that piece of code
involving delay by SycTick feature:

/*Enable SysTick*/
  //Processor clock (AHB)
  SysTick->CTRL |= BIT2;
  //Counting down to zero to asserts the SysTick exception request.
  SysTick->CTRL |= BIT1;
  SysTick->LOAD = 8000 - 1;
void SysTick_Handler(void)
{
  SysTick_Tick++;
  //lcd_writechar('7');
  SCB->ICSR |= BIT25;
}
void delay(int ms)
{
  SysTick_Tick = 0;
  //Enable Systick Counter
  SysTick->CTRL |= BIT0;
  while (SysTick_Tick < ms) {}
  //Disable Systick Counter
  SysTick->CTRL &= ~BIT0;
  SCB->ICSR |= BIT25;
  return;
}

as you see I am trying to clear pending bit of SysTick by SCB->ICSR
|= BIT25;
but clearly after running of delay() function
from inside of EXTI0_IRQHandler() everything hangs..

Best Answer

When you enter the interrupt routine, you need to clear the interrupt source flag. If you do not clear the flag, when you exit the interrupt routine it will just re-enter the routine. This way you will always be stuck in EXTI0_IRQHandler.