Problema en NVIC STM32F100

3

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 de EXTI0_IRQHandler() todo se bloquea ...

    
pregunta peyman khalili

3 respuestas

1

Finalmente, encontré el error. La prioridad es el problema.

Use NVIC_SetPriority(EXTI0_IRQn, 1); para establecer SysTick en un nivel de prioridad más alto que EXTI0_IRQn. Entonces todo va bien.

    
respondido por el peyman khalili
4

Cuando ingresa a la rutina de interrupción, debe borrar el indicador de fuente de interrupción. Si no borra la bandera, cuando salga de la rutina de interrupción, simplemente volverá a entrar en la rutina. De esta manera siempre estarás atrapado en EXTI0_IRQHandler.

    
respondido por el Adam Z
3

El NVIC->ICPR solo elimina el bit pendiente en el NVIC.
Pero, si la señal IRQ al NVIC aún está activa (el registro EXTI PR), el borrado de bits pendiente en el NVIC no tendrá ningún efecto.

En su lugar, debe borrar el origen de la solicitud de interrupción, EXTI->PR = EXTI_PR_PR6 en el ISR. De lo contrario, encadenará esta rutina de interrupción hasta que llegue una de mayor prioridad.

Las definiciones que encuentras en startup.s son débil , las anulas cuando escribe la función real.

Usando NVIC->ISPR[0] |= BIT6 generas una solicitud de interrupción de software. Se borra al ingresar al ISR.

Sugerencia general, al depurar las rutinas de interrupción faltantes, establezca un punto de interrupción aquí:

.section  .text.Default_Handler,"ax",%progbits
Default_Handler:
 Infinite_Loop:
  b  Infinite_Loop  <-------- breakpoint
  .size  Default_Handler, .-Default_Handler
    
respondido por el Jeroen3

Lea otras preguntas en las etiquetas

Comentarios Recientes

/ CA IRQ en el dispositivo STM32F200. - CVE-2013-2973: NVIC: Cambio de formato de archivo (NAT: Fragmentation Check Binary) - Revisión # 2012/02/15: Mayor riesgo de fallas de los módulos AIX debido a elementos eliminados del maestro. (Gracias Cisco) - CAIRP: ILSpi - ACSLowCB: Verificación de fragmentación - CVE-2013-1713: FotoAlgoritmo de información de energía de Windows (EEI) en Preferencias de captura (CVE-2013-3418) - Revisión # 2014/03/03: El HAL no pudo se inicializará en algunos EFI GDE debido a un procedimiento... Lees verder