STM32F103 - NVIC Confusion

0

Mientras lee RM0008 manual de referencia Me confundió sobre cómo usar el NVIC para configurar interrupciones. El manual básicamente redirige el lector al PM0056 manual de programación que, en mi opinión, no hace un gran trabajo explicando cómo usar el Funciones NVIC proporcionadas por CMSIS.

Entonces, estoy intentando configurar una interrupción para el pin 1 de GPIOA usando EXTI Line 1 en una placa NucleoF103, y quiero configurar los bits de prioridad y subprioridad, pero no estoy seguro de cómo hacerlo. El manual RM0008 indica que el NVIC tiene 4 bits de prioridad de interrupción.

CMSIS proporciona funciones como "NVIC_SetPriorityGrouping" y "NVIC_SetPriority" para elegir los bits de prioridad y subprioridad, pero parece que no puedo encontrar una buena explicación de lo que hacen los argumentos en estas funciones.

Parece que el "NVIC_SetPriorityGrouping" cambia algunos valores en el registro AIRCR, que tiene algunos bits para configurar el número de bits de prioridad y subprioridad.

Entonces, por ejemplo, ¿este código es correcto para la configuración e interrupción EXTI en la Línea 1?

#define RESET_WITH_MASK(reg,mask) reg &= ~(mask)
#define SET_WITH_MASK(reg,mask) reg |= (mask)

[...]

//Configure EXTI Line1 to not be masked
SET_WITH_MASK(EXTI->IMR,EXTI_IMR_MR1);

//Configure a rising edge to trigger an interrupt
SET_WITH_MASK(EXTI->RTSR,EXTI_RTSR_TR1);

//Configure EXTI Line1 multiplexer to listen to port A
SET_WITH_MASK(AFIO->EXTICR[0],AFIO_EXTICR1_EXTI1_PA);

//Choose type of priority bits: 3bits for priority, 1bit for subpriority
NVIC_SetPriorityGrouping(1);

//Set priority of EXTI Line1 to 0 (highest priority), subpriority to 1
NVIC_SetPriority(EXTI1_IRQn,0b0001);

//Enable EXTI Line 1 interrupt
NVIC_EnableIRQ(EXTI1_IRQn);

//Enable interrupts
__enable_irq();

Aquí supongo que el argumento para "NVIC_SetPriorityGrouping" elige el número de bits de subprioridad, y que "NVIC_SetPriority" toma los bits de prioridad, la más significativa es la prioridad y la menos importante es la subprioridad.

Obviamente, el pin 1 de GPIOA debe configurarse como una entrada para que esto funcione, pero aparte de eso, ¿me falta algo de configuración? Además, ¿es "__enable_irq ()" realmente necesario?

Cualquier ayuda sería apreciada ya que no pude encontrar ningún buen ejemplo de esto, y me gustaría evitar hacer las configuraciones usando todos esos cambios en los registros de NVIC cuando CMSIS ya proporciona funciones para esto.

    
pregunta Chi

1 respuesta

1

La función NVIC_SetPriority (IRQn, prioridad) escribe la prioridad en ese campo del registro NVIC_IPRx correspondiente a la interrupción especificada por el argumento IRQn. Básicamente asigna la prioridad a la interrupción, como sugiere su nombre. La prioridad se divide en prioridad de grupo (bits superiores) y prioridad secundaria (bits inferiores).

La función NVIC_SetPriorityGrouping (priority_grouping) escribe el valor de su argumento en el campo PRIGROUP del registro SCB_AIRCR. Esto le dice al NVIC cuántos bits de prioridad son la prioridad de grupo y la prioridad secundaria.

Las descripciones de los registros SCB_AIRCR y NVIC_IPRx se encuentran en el Manual de programación.

El Manual de programación describe la agrupación de prioridades:

Solo la prioridad de grupo determina la preferencia de excepciones de interrupción. Cuando el procesador está ejecutando un controlador de excepciones de interrupción, otra interrupción con la misma prioridad de grupo que la interrupción que se está manejando no se adelanta al controlador,

Si varias interrupciones pendientes tienen la misma prioridad de grupo, el campo de subprioridad determina el orden en el que se procesan. Si varias interrupciones pendientes tienen la misma prioridad de grupo y subprioridad, la interrupción con el número IRQ más bajo se procesa primero.

Creo que el argumento NVIC_SetPriorityGrouping () debe tener un valor entre 3 y 7; así 0b100 para configurar para 1 bit de prioridad secundaria. El resto se ve bien.

No necesita el __enable_irq () a menos que haya un prior__disable_irq (). __enable_irq () borra el bit PRIMASK; su valor de reinicio es 0.

    
respondido por el user28910

Lea otras preguntas en las etiquetas