PDF de programación - Capitulo II. Interrupciones

Imágen de pdf Capitulo II. Interrupciones

Capitulo II. Interrupcionesgráfica de visualizaciones

Publicado el 07 de Diciembre del 2018
52 visualizaciones desde el 07 de Diciembre del 2018
1,0 MB
26 paginas
Creado hace 4a (25/10/2014)
Capitulo II.

Interrupciones.
El M4 soporta 240 fuentes de interrupción con 256 niveles de prioridad. Cada interrupción tiene un
vector (Interrupciones Vectorizadas) donde se aloja el código (ISR) que trata la interrupción.
Hay un controlador para las interrupciones llamado NVIC (Nested Vector Interrupt Controller).

Hay dos formas de tratar las prioridades: preemption priorities y sub priorities.
El que tiene mayor prioridad (preemption priorities) se ejecuta en primer lugar, cuando dos
interrupciones tienen la misma prioridad el que tiene mayor prioridad secundaria (sub priorities) se
ejecutará primero. Si ambas tienen igual prioridad y sub-prioridad la interrupción que ocurra primero se
ejecutará primero (orden de llegada).

Los procesadores Cortex M3 y M4 utilizan 8 bits para almacenar las prioridades y sub-prioridades
separados en cinco grupos para elegir la forma en que procesamos la prioridad de la interrupción.

Hay cinco grupos diferentes que podemos establecer.

• Grupo0 - 0 bits para el sobreseimiento, 4 bits para sub prioridad .
• Grupo1 - 1 bits para el sobreseimiento, 3 bits para sub prioridad .
• Group2 - 2 bits para el sobreseimiento, 2 bits para sub prioridad .
• Grupo3 - 3 bits para el sobreseimiento, 1 bits para sub prioridad .
• Grupo4 - 4 bits para el sobreseimiento, 0 bits para sub prioridad .

La función NVIC_PriorityGroupConfig configura los grupos de prioridades.
Si elijo grupo 4 la sintaxis seria NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4) lo que me
dejará 4 bits para NVIC_IRQChannelPreemptionPriority y 0 bits para NVIC_IRQChannelSubPriority.

Pagina 39

Veamos un ejemplo para configurar el la interrupción del Timer3.



NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);

Importante:

Cuando no se especifica NVIC_PriorityGroup por defecto en la biblioteca ST se establece el
Grupo 2, que es de 2 bits para prioridad y 2 bits para sub prioridad.


El archivo misc.c es el encargado de la configuración del NVIC y en el se puede encontrar información
de lo comentado.
Veamos un ejemplo de esto.

Vamos a suponer que tenemos un interrupción EXT1 configurada como PriorityGroup0 y
IRQChannelSubPriority15, también tengo TIM2 configurado en PriorityGroup0
IRQChannelSubPriority0 y finalmente ADC3 es configurado en PriorityGroup1.
EXTI1 y TIM2 tienen NVIC_IRQChannelPreemptionPriority0 por defecto.

Si ha ocurrido la interrupción EXTI1 y un instante después ocurre la interrupción de TIM2 este es
puesto en la cola. Esto se debe a que EXTI1 y TIM2 tienen el mismo IRQChannelPreemptionPriority
pero EXTI1 ha ocurrido primero. Si EXTI1 y TIM2 en el mismo momento, EXTI1 será puesto en la
cola y TIM2 será atendido primero porque TIM2 tiene un NVIC_IRQChannelSubPriority de nivel
superior. (Menor número mayor prioridad).
Por el momento nos interesan las interrupciones por hardware generada por fuentes externas, EXTI0, 1,
2,3, …. estas interrupciones se pueden generar tanto por nivel como por flaco en el pin
correspondiente. Las unidades Cortex M4 tenen características muy avanzadas para reducir la latencia
en el llamado a la ISR.
Las interrupciones se enumeran desde el cero y con números negativos para las excepciones, este micro
tiene interrupciones y excepciones. El archivo stm32f4xx.h proporciona el número de interrupción y de
excepción.
typedef enum IRQn
{
/****** Cortex-M4 Processor Exceptions Numbers*******************************************/
NonMaskableInt_IRQn = -14, /*!< 2 Non Maskable Interrupt*/
MemoryManagement_IRQn = -12, /*!< 4 Cortex-M4 Memory Management Interrupt*/
BusFault_IRQn = -11, /*!< 5 Cortex-M4 Bus Fault Interrupt */
UsageFault_IRQn = -10, /*!< 6 Cortex-M4 Usage Fault Interrupt */
SVCall_IRQn = -5, /*!< 11 Cortex-M4 SV Call Interrupt */
DebugMonitor_IRQn = -4, /*!< 12 Cortex-M4 Debug Monitor Interrupt */
PendSV_IRQn = -2, /*!< 14 Cortex-M4 Pend SV Interrupt */
SysTick_IRQn = -1, /*!< 15 Cortex-M4 System Tick Interrupt */
/****** STM32 specific Interrupt Numbers*************************************************/
WWDG_IRQn = 0, /*!< Window WatchDog Interrupt */
PVD_IRQn = 1, /*!< PVD through EXTI Line detection Interrupt*/
TAMP_STAMP_IRQn = 2, /*!< Tamper and TimeStamp */

Pagina 40

RTC_WKUP_IRQn = 3, /*!< RTC Wakeup interrupt through the EXTI line */
FLASH_IRQn = 4, /*!< FLASH global Interrupt */
RCC_IRQn = 5, /*!< RCC global Interrupt */
EXTI0_IRQn = 6, /*!< EXTI Line0 Interrupt */
........
etc....

En el caso del KEIL, ARM proporciona dentro del archivo startup_stm32f4xx.s una plantilla para el
manejo de interrupciones y excepciones.
; External Interrupts
DCD WWDG_IRQHandler ; Window WatchDog
DCD PVD_IRQHandler ; PVD through EXTI Line detection
DCD TAMP_STAMP_IRQHandler ; Tamper and TimeStamps through the EXTI line
DCD RTC_WKUP_IRQHandler ; RTC Wakeup through the EXTI line
DCD FLASH_IRQHandler ; FLASH
DCD RCC_IRQHandler ; RCC
DCD EXTI0_IRQHandler ; EXTI Line0
DCD EXTI1_IRQHandler ; EXTI Line1
DCD EXTI2_IRQHandler ; EXTI Line2
DCD EXTI3_IRQHandler ; EXTI Line3
DCD EXTI4_IRQHandler ; EXTI Line4
DCD DMA1_Stream0_IRQHandler ; DMA1 Stream 0

Normalmente encontrará que los servicios de interrupciones se escriben en el archivo stm32f4xx_it.c
sin embargo las ISR son funciones del tipo weak las rutinas se pueden escribir directamente en la
aplicación como puede observar en el código siguiente que se agrega como una función mas en el
archivo principal.
void EXTI0_IRQHandler(void){ Mismo nombre declarado en startup_stm32f4xx.s
if(EXTI_GetITStatus(EXTI_Line0) != RESET){
GPIO_ToggleBits(GPIOD, GPIO_Pin_13); // Cambio el estado del pin.
EXTI_ClearITPendingBit(EXTI_Line0); // Borra la bandera de la interrupción.
}
}

....

etc..

Como se mencionaba anteriormente los Cortex M tiene una tecnología muy eficiente para reducir la
latencia entre interrupciones.

El siguiente ejemplo pone en practica lo visto con la interrupción en PA0.
La idea es lograr encender el LED anaranjado cada vez que se oprime el botón de usuario en la placa
entrenadora.

Pagina 41

Hay 16 líneas de interrupción externa EXTI0, EXTI1, EXTI2......EXTI15 con una gran cantidad de pines
GPIO que se pueden configurar para interrupciones externas. En este caso usaremos la línea 0 y el pin
PA0.

(Es de notar que la Discovery no tiene ningún condensador
aplicado al pulsador por lo tanto es de esperar que el
funcionamiento no será optimo a no se que agregue como
indico anteriormente).

En el siguiente ejemplo no se ha especificado grupo de
prioridades por lo tanto por defecto se asignan el Grupo 2
para el tratamiento de las prioridades.

Pagina 42

/**********************************************************************************
* Nombre : INT_EXT.c
* Descripción : Funcionamiento de las interrupción ext. pin23 (PA0).
* Target : STM32F407VG
* ToolChain : MDK-ARM
* IDE : uVision 4
*
**********************************************************************************/
#include "stm32f4xx_rcc.h"
#include "stm32f4xx_gpio.h"
void Config_Int(void);
void Configurar_LED(void);
unsigned char bandera = 0;

www.firtec.com.ar

int main(void){
Configurar_LED(); // Configura pin del LED
Config_Int(); //Configura EXTI Line0 (Pin PA0) en modo interrupcion


Programa principal

while (1){
// Espera la interrupción.

}
}

Función que configura puerto y pin para el LED

// puerto GPIOD

void Configurar_LED()
{
GPIO_InitTypeDef GPIO_InitStructure;// Estructura para la configuración del

RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
// El pin será push/pull
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // Velocidad del puerto
GPIO_Init(GPIOD, &GPIO_InitStructure); // Pasa la config. a la estructura.
}
void Config_Int(void){
GPIO_InitTypeDef GPIO_InitStructure; // Estructura para los pines GPIO
NVIC_InitTypeDef NVIC_InitStructure; // Estructura para el NVIC
EXTI_InitTypeDef EXTI_InitStructure; // Estructura para la interrupción.

Función que configura la interrupción por PA0

// Habilita el reloj
// Configura el pin 13
// El pin será salida

//Habilita el reloj para el puerto GPIOA
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
// Habilita SYSCFG clock
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);

// Configura pin PA0 como entrada y flotante
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_Init(GPIOA, &GPIO_InitStructure);

// Conecta la interrupción al pin PA0
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA, EXTI_PinSource0);
  • Links de descarga
http://lwp-l.com/pdf14458  

Comentarios de: Capitulo II. Interrupciones (0)


No hay comentarios
 

Comentar...

Nombre
Correo (no se visualiza en la web)
Valoración
Comentarios
Es necesario revisar y aceptar las políticas de privacidad

Revisar política de publicidad