Estoy utilizando la placa de descubrimiento STM32VL (STM32f100rb6) .. Escribí el siguiente código para 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');
}
y
int main(void)
{
Interrupt_Init();
while (1)
{
}
}
void EXTI0_IRQHandler(void)
{
//NVIC->ICPR[0] |= BIT6;
lcd_writechar('2');
}
como se ve en Interrupt_Init()
I user NVIC->ISPR[0] |= BIT6;
frase para habilitar suavemente exti0-IRQ. así que la subrutina void EXTI0_IRQHandler(void)
debe ejecutarse y obtuve '2' en la pantalla LCD. pero como NVIC->ISPR[0] |= BIT6;
ejecuta la siguiente línea ( lcd_writechar('1');
) nunca se ejecuta ... pero cuando comenté ( NVIC->ISPR[0] |= BIT6;
) obtuve '1' en la pantalla LCD ... ¿qué está pasando?
Actualización:
Miro más lejos en el archivo "startup_stm32f10x_md_vl.s" en mi proyecto como archivo de inicio:
.section .text.Default_Handler,"ax",%progbits Default_Handler: Infinite_Loop: b Infinite_Loop .size Default_Handler, .-Default_Handler
y:
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 ...
y:
.weak EXTI0_IRQHandler .thumb_set EXTI0_IRQHandler,Default_Handler
Parece que "EXTI0_IRQHandler" siempre es igual a "Default_Handler" en mis proyectos por lo que causan un bucle infinito como definimos anteriormente.
Creo que esta parte:
void EXTI0_IRQHandler(void) { NVIC->ICPR[0] |= BIT6; lcd_writechar('2'); }
nunca influye en la definición de "EXTI0_IRQHandler". ¿por qué?
Actualización:
¿Hay alguna manera de saltar a EXTI0_IRQHandler sin implementar nada en periférico ?? Como asm ("b 0x58 ")? Mi propósito es estar seguro de las configuraciones del núcleo y luego trabajar ¿En configuraciones periféricas?
Actualización:
Casi encontré un problema pero necesito ayuda para solucionarlo ... después de muchos examen y uso de funciones de depuración encontré este pedazo de código es defectuoso:
void EXTI0_IRQHandler() { lcd_writechar('2'); LED_ON(); NVIC->ICPR[0] |= BIT6; }
en detalle
lcd_writechar('2');
causa para emitir porque dentro de la función Estoy usando la función de retardo (). Este es ese pedazo de código implicando retraso por la característica de SycTick:/*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; }
como ves, estoy intentando borrar un bit pendiente de SysTick con
SCB->ICSR |= BIT25;
pero claramente después de ejecutar la función delay () desde dentro deEXTI0_IRQHandler()
todo se bloquea ...