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
but clearly after running of delay() function
|= BIT25;
from inside ofEXTI0_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.