Proceso de configuración de la interrupción externa EXTI en STM32 y problemas comunes difíciles

Tabla de contenido

Interrupción externa EXTI

Introducción a la interrupción externa STM32

Correspondencia entre líneas de interrupción externas y 112 puertos IO

Introducción a las funciones del servicio de interrupción

Principios de la solicitud de eventos de interrupción e interrupción externa

Interrumpir el flujo de ejecución

Interrumpir el flujo de ejecución de eventos

El papel del registro de máscara

La diferencia entre interrupción y evento

Interrupciones y eventos

Ejemplo simple

¿Por qué borrar el bit de bandera de interrupción en la función de servicio de interrupción?

¿Por qué debería habilitar las funciones relacionadas con AFIO en APB2 al configurar la función de interrupción?

Registros relacionados con AFIO

La diferencia entre reasignación y reutilización de puertos

Ejemplo de código

C Principal

LED.c

LED.h

CLAVE.c

KEY.h

EXTI.c

EXTI.h


Interrupción externa EXTI

Introducción a la interrupción externa STM32

 

Correspondencia entre líneas de interrupción externas y 112 puertos IO

 

Cada uno de los 112 puertos IO se puede conectar a su propia línea de interrupción externa Dado que solo hay 16 líneas de interrupción externas, cada 7 puertos IO utilizan una línea de interrupción externa, por ejemplo: PA4, PB4, PC4 ... PG4 comparte el bus de control de interrupciones EXTI4. Debido a que es compartido, solo un puerto IO de PA4, PB4, PC4 ... PG4 ocupa la línea de interrupción externa en cualquier momento.

Escriba la descripción de la imagen aquí

Introducción a las funciones del servicio de interrupción

 

Principios de la solicitud de eventos de interrupción e interrupción externa

 

Interrumpir el flujo de ejecución

Pasos para interrumpir la ejecución

Operación detallada

1

Cambio de nivel de línea de entrada

2

Circuito de detección de bordes (hay tres modos de detección: borde ascendente, borde descendente y borde ascendente y borde descendente)

3

② Circuito de puerta Y (en este momento, si el registro de solicitud de interrupción de software se establece en 1, la puerta O no dependerá del valor de retorno del circuito de detección de borde y siempre devolverá 1)

4

La señal se pasa al "registro de solicitud pendiente"

5

La señal pasa a través del circuito de la puerta AND (si el registro de máscara de interrupción devuelve 0, no importa qué valor devuelva el registro pendiente hará que el registro de control de interrupciones NVIC reciba una señal de bajo nivel)

6

El controlador NVIC accederá directamente a la dirección del vector de interrupción para ejecutar la función de servicio de interrupción correspondiente

Generalmente decimos "Solo cuando se suspende la interrupción, el bit de bandera de interrupción activará la interrupción y ejecutará la función de servicio de interrupción". Esta oración significa "Cuando se solicita que se habilite el registro de suspensión, una vez que se cumple la condición de activación de la interrupción, es Cuando el circuito de detección de flanco vuelve a un nivel válido, el bit del indicador de interrupción se establecerá en 1 (el bit del indicador de interrupción está en el controlador NVIC). Después de que se cumplan las dos condiciones de "posición de indicador de interrupción 1 y solicitud de interrupción suspendida", la función de servicio de interrupción se ejecutará inmediatamente. ".

Hay dos funciones de biblioteca que deben distinguirse específicamente aquí:

USART_ClearFlag

Bandera completa clara

USART_ClearITPendingBit

Bandera de interrupción clara

Interrumpir el flujo de ejecución de eventos

Pasos para interrumpir la ejecución

Operación detallada

1

Cambio de nivel de línea de entrada

2

Circuito de detección de bordes (hay tres modos de detección: borde ascendente, borde descendente y borde ascendente y borde descendente)

3

② Circuito de puerta Y (en este momento, si el registro de solicitud de interrupción de software se establece en 1, la puerta O no dependerá del valor de retorno del circuito de detección de borde y siempre devolverá 1)

4

La señal devuelta por la puerta O ingresa al circuito de la puerta Y junto con el registro de máscara de evento. Si el registro de máscara de evento devuelve 0, el circuito de puerta Y no depende de la señal devuelta por la puerta O y devuelve 0 directamente.

5

Si la puerta AND devuelve 1, se iniciará el generador de impulsos y se iniciarán otras funciones directamente, por ejemplo: el disparador de interrupción externo puede disparar directamente el ADC

6

Utilice activadores de pulso para vincular los periféricos correspondientes

El papel del registro de máscara

Podemos aprender del proceso anterior:

Interrupción del registro de máscara

El retorno del registro de máscara a 0 hará que la puerta AND vuelva a 0 directamente, es decir, un nivel no válido. En este momento, la interrupción de NVIC no se activará independientemente de si hay una solicitud de interrupción

Registro de máscara de eventos

El retorno del registro de máscara a 0 hará que la puerta AND vuelva a 0 directamente, es decir, un nivel no válido. En este punto, no importa si la puerta OR devuelve un nivel válido, no habilitará el disparo de pulso y no causará la interrupción del evento.

La diferencia entre interrupción y evento

Interrupciones y eventos

Interrumpir

La CPU necesita participar en la función de servicio de interrupción del software para completar el resultado después de la interrupción

evento

El generador de pulsos genera un pulso y el hardware completa automáticamente el resultado de este evento. Por supuesto, los componentes de enlace correspondientes deben configurarse primero, como causar la operación DMA, conversión AD ... etc.

Ejemplo simple

La E / S externa activa la conversión AD para medir el peso de los elementos externos; si usa el canal de interrupción tradicional, debe activar la E / S para generar una interrupción externa, el programa de servicio de interrupción externa inicia la conversión AD y la conversión AD completa el programa de servicio de interrupción para enviar el resultado final; si es así Al usar el canal de eventos, la E / S se activa para generar eventos, y luego el enlace activa la conversión de AD, y la conversión de AD completa el programa de servicio de interrupción para enviar el resultado final; por el contrario, este último no requiere software para participar en la activación de AD, y la velocidad de respuesta también es más rápida; si usa eventos Al activar la operación de DMA, algunas tareas de vinculación se pueden completar sin la participación del software.

¿Por qué borrar el bit de bandera de interrupción en la función de servicio de interrupción?

Si al ingresar la interrupción no se borra el bit de la bandera, luego de que finaliza la rutina del servicio de interrupción, debido a que el bit de la bandera todavía está establecido y la interrupción está permitida, la interrupción se ingresará nuevamente y el programa de interrupción siempre se ejecutará.

¿Por qué debería habilitar las funciones relacionadas con AFIO en APB2 al configurar la función de interrupción?

Registros relacionados con AFIO

Registro de control de eventos (AFIO_EVCR)

Registro de configuración de E / S de depuración y reasignación de multiplexación (AFIO_MAPR)

Registro de configuración de interrupción externa 1 (AFIO_EXTICR1)

Registro de configuración de interrupción externa 2 (AFIO_EXTICR2)

Registro de configuración de interrupción externa 3 (AFIO_EXTICR3)

Registro de configuración de interrupción externa 4 (AFIO_EXTICR4)

Nota: AFIO originalmente significa "E / S de función alternativa", no solo para la reasignación de puertos. Siempre que sea antes de leer y escribir los registros AFIO_EVCR, AFIO_MAPR y AFIO_EXTICRX, el reloj AFIO debe estar encendido, ¡no solo al reasignar! ! !

La diferencia entre reasignación y reutilización de puertos

Reutilización de puertos

Siempre que se use stm32, se necesitan periféricos. Los periféricos se comparten (multiplexan) con pines GPIO, es decir, algunos pines se pueden usar como entrada y salida, o como periféricos con ciertas funciones (como ADC, puerto serie) Etc.) puerto pin

Reasignación de puertos

La función de multiplexación (AFIO) se deriva de diferentes pines GPIO. Stm32 introduce el concepto de reasignación de pines periféricos. Los puertos periféricos incorporados generalmente tienen pines predeterminados. También puede configurar el registro de reasignación para cambiar el Mapeo de puertos a otros pines

Ejemplo de código

C Principal

#include "led.h"  
#include "exti.h"  
#include "key.h"  
#include "stm32f10x.h"  
  
int main()  
{  
    LED_InitConfig();  
    KEY_InitConfig();  
    EXTI_InitConfig();  
      
    while(1);  
}  
  
void EXTI4_IRQHandler()  
{  
    if(EXTI_GetITStatus(EXTI_Line4) == SET)  // 如果中断标志位为1,说明中断触发
    {  
        LED0 = !LED0;  
    }  
    EXTI_ClearITPendingBit(EXTI_Line4); // 清除中断标志位  
}  

 

LED.c

#include "led.h"  
#include "stm32f10x.h"  
  
void LED_InitConfig()  
{  
    GPIO_InitTypeDef GPIO_InitStructure;  
      
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); // 使能GPIOB的外部时钟  
      
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; // 配置LED0的属性  
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;  
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;  
    GPIO_Init(GPIOB, &GPIO_InitStructure);  
      
    GPIO_SetBits(GPIOB, GPIO_Pin_5); // 初始化LED0的电平  
}  

 

LED.h

#ifndef _LED_H  
#define _LED_H  
  
#include "sys.h"  
  
void LED_InitConfig();  
  
#define LED0 PBout(5)  
  
#endif  

 

CLAVE.c

#include "key.h"  
#include "stm32f10x.h"  
  
  
void KEY_InitConfig()  
{  
    GPIO_InitTypeDef GPIO_InitStructure;  
      
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE, ENABLE); // 使能GPIOE的时钟  
      
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; // 配置KEY0的属性  
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;  
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;  
    GPIO_Init(GPIOE, &GPIO_InitStructure);  
}  

 

KEY.h

#ifndef _KEY_H  
#define _KEY_H  
  
void KEY_InitConfig();  
  
#endif  

 

EXTI.c

#include "exti.h"  
#include "key.h"  
#include "stm32f10x.h"  
  
  
void EXTI_InitConfig()  
{   
    NVIC_InitTypeDef NVIC_InitStructure;  
    EXTI_InitTypeDef EXTI_InitStructure;  
      
    KEY_InitConfig(); // 初始化KEY0  
      
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); // 使能AFIO时钟  
      
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); // 配置中断分组  
      
    NVIC_InitStructure.NVIC_IRQChannel = EXTI4_IRQn; // 配置中断优先级,使能中断通道  
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;  
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;  
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;  
    NVIC_Init(&NVIC_InitStructure);  
      
    GPIO_EXTILineConfig(GPIO_PortSourceGPIOE, GPIO_PinSource4); // 配置GPIO端口引脚与中断线的关系  
      
    EXTI_InitStructure.EXTI_Line = EXTI_Line4; // EXTI外部中断初始化配置  
    EXTI_InitStructure.EXTI_LineCmd = ENABLE;  
    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;  
    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;  
    EXTI_Init(&EXTI_InitStructure);  
}  

 

EXTI.h

#ifndef _EXTI_H  
#define _EXTI_H  
  
void EXTI_InitConfig();  
  
#endif  

 

 

Supongo que te gusta

Origin blog.csdn.net/weixin_45590473/article/details/107973012
Recomendado
Clasificación