STM32_EXTI_外部中断

文章目录

  • 一、EXTI
  • 二、EXTI功能框图
    • [   1、EXTI框图](#   1、EXTI框图)
    • [   2、EXTI框图详解](#   2、EXTI框图详解)
    • [   3、中断/事件线](#   3、中断/事件线)
    • [   4、EXTI结构体详解](#   4、EXTI结构体详解)
  • 三、GPIO中断
    • [   1、编程要点](#   1、编程要点)
    • [   2、硬件设计](#   2、硬件设计)
    • [   3、编程代码](#   3、编程代码)

一、EXTI

EXTI:External interrupt / event controller 外部 中断/事件 控制器

EXTI(External interrupt/event controller)---外部中断/事件控制器,管理了控制器的20个中断/事件线。

每个中断/事件线都对应有一个边沿检测器,可以实现输入信号的上升沿检测和下降沿的检测。

EXTI可以实现对每个中断/事件线进行单独配置, 可以单独配置为中断或者事件,以及触发事件的属性。

二、EXTI功能框图

1、EXTI框图

2、EXTI框图详解

编号1:输入线

EXTI控制器有19个中断/事件输入线,这些输入线可以通过寄存器设置为任意一个GPIO,也可以是一些外设的事件。

输入线一般是存在电平变化的信号。

编号2:边沿检测电路

根据上升沿触发选择寄存器(EXTI_RTSR)和下降沿触发选择寄存器(EXTI_FTSR)对应位的设置来控制信号触发。

边沿检测电路以输入线作为信号输入端,如果检测到有边沿跳变就输出有效信号1给编号3电路,否则输出无效信号0。

可以设置只有上升沿触发、只有下降沿触发或者上升沿和下降沿都触发。

编号3:或门电路

输入来自编号2电路,另外一个输入来自软件中断事件寄存器(EXTI_SWIER)。

EXTI_SWIER允许我们通过程序控制就可以启动中断/事件线。

或门电路作用就是有1就为1。

这两个输入随便一个有有效信号1就可以输出1给编号4和编号6电路。

编号4:与门电路

一个输入是编号3电路,另外一个输入来自中断屏蔽寄存器(EXTI_IMR)。

门电路要求输入都为1才输出1, 导致的结果是如果EXTI_IMR设置为0时,

那不管编号3电路的输出信号是1还是0,最终编号4电路输出的信号都为0;

如果EXTI_IMR设置为1时, 最终编号4电路输出的信号才由编号3电路的输出信号决定。

编号5:输出到NVIC

将EXTI_PR寄存器内容输出到NVIC内,从而实现系统中断事件控制。

编号6:与门电路

一个输入来自编号3电路, 另外一个输入来自事件屏蔽寄存器(EXTI_EMR)。

如果EXTI_EMR设置为0时,那不管编号3电路的输出信号是1还是0,最终编号6电路输出的信号都为0;

如果EXTI_EMR设置为1时,最终编号6电路输出的信号才由编号3电路的输出信号决定。

编号7:脉冲发生器电路

当它的输入端,即编号6电路的输出端,是一个有效信号1时就会产生一个脉冲;如果输入端是无效信号就不会输出脉冲。

编号8:脉冲信号

脉冲信号可以给其他外设电路使用,比如定时器TIM、模拟数字转换器ADC等。

总结:

EXTI可分为两大部分功能,一个是产生中断12345 ,另一个是产生事件 123678。

3、中断/事件线

EXTI有20个中断/事件线,每个GPIO都可以被设置为输入线,占用EXTI0至EXTI15, 还有另外七根用于特定的外设事件.

EXTI16-19,4根特定外设中断/事件线由外设触发。

EXTI0-15用于GPIO,通过编程控制可以实现任意一个GPIO作为EXTI的输入源。

EXTI0可以通过AFIO的外部中断配置寄存器1(AFIO_EXTICR1)的EXTI0[3:0]位选择配置为PA0、 PB0、PC0、PD0、PE0、PF0、PG0、PH0或者PI0。

4、EXTI结构体详解

c 复制代码
		typedef struct {
		    uint32_t EXTI_Line;                 // 中断/事件线
		    EXTIMode_TypeDef EXTI_Mode;         // EXTI模式
		    EXTITrigger_TypeDef EXTI_Trigger;   // 触发类型
		    FunctionalState EXTI_LineCmd;       // EXTI使能
		} EXTI_InitTypeDef;

XTI_Line:

EXTI中断/事件线选择,可选EXTI0至EXTI19,可参考表 EXTI中断_事件线 选择。

EXTI_Mode:

EXTI模式选择,可选为产生中断(EXTI_Mode_Interrupt)或者产生事件(EXTI_Mode_Event)。

EXTI_Trigger:

EXTI边沿触发事件,可选上升沿触发(EXTI_Trigger_Rising)、 下降沿触发( EXTI_Trigger_Falling)或者上升沿和下降沿都触发( EXTI_Trigger_Rising_Falling)。

EXTI_LineCmd:

控制是否使能EXTI线,可选使能EXTI线(ENABLE)或禁用(DISABLE)。

三、GPIO中断

1、编程要点

1,初始化要连接到EXTI的 GPIO。

2,初始化EXTI用于产生中断事件。

3,初始化NVIC,用于处理中断。

4,编写中断服务函数。

5,main函数。

2、硬件设计

3、编程代码

按键和EXTI宏定义

按键和EXTI宏定义 EXTI.h文件内

c 复制代码
			//引脚定义
			#define KEY1_INT_GPIO_PORT         GPIOA
			#define KEY1_INT_GPIO_CLK          (RCC_APB2Periph_GPIOA\
			                                    |RCC_APB2Periph_AFIO)
			#define KEY1_INT_GPIO_PIN          GPIO_Pin_0
			
			#define KEY1_INT_EXTI_PORTSOURCE   GPIO_PortSourceGPIOA
			#define KEY1_INT_EXTI_PINSOURCE    GPIO_PinSource0
			#define KEY1_INT_EXTI_LINE         EXTI_Line0
			#define KEY1_INT_EXTI_IRQ          EXTI0_IRQn
			
			#define KEY1_IRQHandler            EXTI0_IRQHandler
			
			#define KEY2_INT_GPIO_PORT         GPIOC
			#define KEY2_INT_GPIO_CLK          (RCC_APB2Periph_GPIOC\
			                                    |RCC_APB2Periph_AFIO)
			#define KEY2_INT_GPIO_PIN          GPIO_Pin_13
			
			#define KEY2_INT_EXTI_PORTSOURCE   GPIO_PortSourceGPIOC
			#define KEY2_INT_EXTI_PINSOURCE    GPIO_PinSource13
			#define KEY2_INT_EXTI_LINE         EXTI_Line13
			
			#define KEY2_INT_EXTI_IRQ          EXTI15_10_IRQn

嵌套向量中断控制器NVIC配置

嵌套向量中断控制器NVIC配置 EXTI.c文件内

c 复制代码
			static void NVIC_Configuration(void)
			{
			    NVIC_InitTypeDef NVIC_InitStructure;
			
			    /* 配置NVIC为优先级组1 */
			    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
			
			    /* 配置中断源:按键1 */
			    NVIC_InitStructure.NVIC_IRQChannel = KEY1_INT_EXTI_IRQ;
			    /* 配置抢占优先级:1 */
			    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
			    /* 配置子优先级:1 */
			    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
			    /* 使能中断通道 */
			    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
			    NVIC_Init(&NVIC_InitStructure);
			
			    /* 配置中断源:按键2,其他使用上面相关配置 */
			    NVIC_InitStructure.NVIC_IRQChannel = KEY2_INT_EXTI_IRQ;
			    NVIC_Init(&NVIC_InitStructure);
			}

EXTI中断配置.

EXTI中断配置 EXTI.c文件内

c 复制代码
			void EXTI_Key_Config(void)
			{
			    GPIO_InitTypeDef GPIO_InitStructure;
			    EXTI_InitTypeDef EXTI_InitStructure;
			
			    /*开启按键GPIO口的时钟*/
			    RCC_APB2PeriphClockCmd(KEY1_INT_GPIO_CLK,ENABLE);
			
			    /* 配置 NVIC 中断*/
			    NVIC_Configuration();
			
			    /*--------------------------KEY1配置---------------------*/
			    /* 选择按键用到的GPIO */
			    GPIO_InitStructure.GPIO_Pin = KEY1_INT_GPIO_PIN;
			    /* 配置为浮空输入 */
			    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
			    GPIO_Init(KEY1_INT_GPIO_PORT, &GPIO_InitStructure);
			
			    /* 选择EXTI的信号源 */
			    GPIO_EXTILineConfig(KEY1_INT_EXTI_PORTSOURCE, \
			                        KEY1_INT_EXTI_PINSOURCE);
			    EXTI_InitStructure.EXTI_Line = KEY1_INT_EXTI_LINE;
			
			    /* EXTI为中断模式 */
			    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
			    /* 上升沿中断 */
			    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
			    /* 使能中断 */
			    EXTI_InitStructure.EXTI_LineCmd = ENABLE;
			    EXTI_Init(&EXTI_InitStructure);
			
			    /*--------------------------KEY2配置------------------*/
			    /* 选择按键用到的GPIO */
			    GPIO_InitStructure.GPIO_Pin = KEY2_INT_GPIO_PIN;
			    /* 配置为浮空输入 */
			    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
			    GPIO_Init(KEY2_INT_GPIO_PORT, &GPIO_InitStructure);
			
			    /* 选择EXTI的信号源 */
			    GPIO_EXTILineConfig(KEY2_INT_EXTI_PORTSOURCE, \
			                        KEY2_INT_EXTI_PINSOURCE);
			    EXTI_InitStructure.EXTI_Line = KEY2_INT_EXTI_LINE;
			
			    /* EXTI为中断模式 */
			    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
			    /* 下降沿中断 */
			    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
			    /* 使能中断 */
			    EXTI_InitStructure.EXTI_LineCmd = ENABLE;
			    EXTI_Init(&EXTI_InitStructure);
			}

EXTI中断服务函数

EXTI中断服务函数 stm32f10x_it.c内

c 复制代码
			void EXTI0_IRQHandler(void)
			{
			            //确保是否产生了EXTI Line中断
			    if (EXTI_GetITStatus(KEY1_INT_EXTI_LINE) != RESET) {
			        // LED1 取反
			        LED1_TOGGLE;
			        //清除中断标志位
			        EXTI_ClearITPendingBit(KEY1_INT_EXTI_LINE);
			    }
			}
			
			
			void EXTI15_10_IRQHandler(void)
			{
			            //确保是否产生了EXTI Line中断
			    if (EXTI_GetITStatus(KEY2_INT_EXTI_LINE) != RESET) {
			        // LED2 取反
			        LED2_TOGGLE;
			        //清除中断标志位
			        EXTI_ClearITPendingBit(KEY2_INT_EXTI_LINE);
			    }
			}

Main函数

c 复制代码
			int main(void)
			{
			    /* LED 端口初始化 */
			    LED_GPIO_Config();
			
			    /* 初始化EXTI中断,按下按键会触发中断,
			    *  触发中断会进入stm32f10x_it.c文件中的函数
			    *  KEY1_IRQHandler和KEY2_IRQHandler,处理中断,反转LED灯。
			    */
			    EXTI_Key_Config();
			
			    /* 等待中断,由于使用中断方式,CPU不用轮询按键 */
			    while (1) {
			    }
			}
相关推荐
悠哉悠哉愿意3 小时前
【物联网学习笔记】RTC
笔记·单片机·嵌入式硬件·物联网·学习·实时音视频
YY_Share3 小时前
Console 接口介绍及电路设计
嵌入式硬件·硬件工程
工控小机3 小时前
STM32远程下载、调试终端介绍
stm32·单片机·嵌入式硬件·物联网
YY_Share3 小时前
主板调速风扇电路设计
单片机·嵌入式硬件·硬件工程
学嵌入式的小杨同学3 小时前
STM32 进阶封神之路(十四):语音交互实战 ——SU03T 语音识别模块从固件制作到 STM32 控制(串口通信 + 命令响应)
c++·stm32·单片机·嵌入式硬件·架构·硬件架构·ux
科技前瞻观察3 小时前
赋能智算升级|基于极海G32R501实时控制DSP MCU的AI服务器电源应用方案
服务器·人工智能·单片机
程序员杰森4 小时前
ESP32开发板+TB6612 x 2 四电机小车笔记
笔记·单片机·嵌入式硬件
阿拉斯攀登4 小时前
第 10 篇 RK 平台安卓驱动实战 3:PWM 驱动开发,实现 LED 呼吸灯 + 电机调速
驱动开发·嵌入式硬件·pwm·瑞芯微·嵌入式驱动·rk3576·嵌入式安卓
集芯微电科技有限公司4 小时前
氮化镓GaN FET/GaN HEMT功率驱动器选型一览表
人工智能·单片机·嵌入式硬件·深度学习·神经网络·生成对抗网络