一、EXTI 简介

EXTI(External interrupt/event controller)—外部中断/事件控制器,管理了控制器的 20个中断/事件线。每个中断/事件线都对应有一个边沿检测器,可以实现输入信号的上升沿检测和下降沿的检测。EXTI 可以实现对每个中断/事件线进行单独配置,可以单独配置为中断或者事件,以及触发事件的属性。

二、EXTI框图



在图中可以看到很多在信号线上打一个斜杠并标注“20”字样,这表示在控制器内部的信号线有 20 路,我们只要明白其中一路的原理即可。

  • 输入线:EXTI 控制器有 20 个中断/事件输入线,这些输入线可以通过寄存器设置为任意一个 GPIO,也可以是一些外设的事件,输入线一般是存在电平变化的信号。
  • 边沿检测电路:它会根据上升沿触发选择寄存(EXTI_RTSR)和下降沿触发选择寄存器(EXTI_FTSR)对应位的设置来控制信号触发。边沿检测电路以输入线作为信号输入端,如果检测到有边沿跳变就输出有效信号 1 ,否则输出无效信号0。而 EXTI_RTSR 和 EXTI_FTSR 两个寄存器可以控制器需要检测哪些类型的电平跳变过程,可以是只有上升沿触发、只有下降沿触发或者上升沿和下降沿都触发。
  • NVIC中断控制器:NVIC中断控制器接收到EXTI_PR 寄存器发送的内容,实现中断的发生。
  • 脉冲发生器:脉冲发生器发送信号后会产生事件线路,脉冲信号可以给其他外设电路使用,比如定时器 TIM、模拟数字转换器 ADC等等,这样的脉冲信号一般用来触发 TIM 或者 ADC开始转换。

现在可以知道EXTI 可分为两大部分功能,一个是产生中断,另一个是产生事件。产生中断线路目的是把输入信号输入到 NVIC,进一步会运行中断服务函数,实现功能,这样是软件级的。而产生事件线路目的就是传输一个脉冲信号给其他外设使用,并且是电路级别的信号传输,属于硬件级的。

三、中断/事件线

EXTI有 20个中断/事件线,每个 GPIO都可以被设置为输入线,每个输入线的来源如图所示:



从图中可以看出STM32的外部中断只有16个,又是怎么使每个GPIO都可以实现中断了,通过编程控制可以实现任意一个 GPIO作为 EXTI的输入源。



从上图可知EXTI0 可以通过 AFIO 的外部中断配置寄存器 1(AFIO_EXTICR1)的EXTI0[3:0]位选择配置为 PA0、PB0、PC0、PD0、PE0、PF0、PG0,其他 EXTI线(EXTI中断/事件线)使用配置都是类似的。

四、EXTI 寄存器

  1. 中断屏蔽寄存器(EXTI_IMR)

  2. 事件屏蔽寄存器(EXTI_EMR)

  3. 上升沿触发选择寄存器(EXTI_RTSR)



    注意: 外部唤醒线是边沿触发的,这些线上不能出现毛刺信号。在写EXTI_RTSR寄存器时,在外部中断线上的上升沿信号不能被识别,挂起位也不会被置位。在同一中断线上,可以同时设置上升沿和下降沿触发。即任一边沿都可触发中断

  4. 下降沿触发选择寄存器(EXTI_FTSR)



    注意: 外部唤醒线是边沿触发的,这些线上不能出现毛刺信号。在写EXTI_FTSR寄存器时,在外部中断线上的下降沿信号不能被识别,挂起位不会被置位。在同一中断线上,可以同时设置上升沿和下降沿触发。即任一边沿都可触发中断。

  5. 软件中断事件寄存器(EXTI_SWIER)

  6. 挂起寄存器(EXTI_PR)

  7. 外部中断/事件寄存器映像

五、EXTI 程序分析

  1. EXTI 初始化程序的结构体
typedef struct
{
uint32_t EXTI_Line; // 中断/事件线
EXTIMode_TypeDef EXTI_Mode; // EXTI 模式
EXTITrigger_TypeDef EXTI_Trigger; // 触发类型
FunctionalState EXTI_LineCmd; // EXTI 使能
}EXTI_InitTypeDef;
  1. 初始化GPIO
//将GPIOA_0设置为下拉输入
void KEY_Init(void) //IO初始化
{
GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); //使能PORTB,PORTE时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE); //使能AFIO复用功能时钟 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; // 0 pin
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; // 设置成下拉输入
GPIO_Init(GPIOA, &GPIO_InitStructure); // 初始化GPIOA_0 }
  1. 初始化EXTI

    //GPIOA_0 中断线以及中断初始化配置   下降沿触发
void EXTIX_Init(void)
{
EXTI_InitTypeDef EXTI_InitStructure; GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource0); // 选择GPIOA_0作为中断EXTI0的线路 EXTI_InitStructure.EXTI_Line=EXTI_Line0; //中断/事件线
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; // 中断触发
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising; // 下降沿触发
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure); //根据EXTI_InitStruct中指定的参数初始化外设EXTI寄存器
}
  1. 配置 GPIO 中断
    //初始化中断
void NVICX_Init(void)
{
NVIC_InitTypeDef NVIC_InitStructure; NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn; //使能按键WK_UP所在的外部中断通道
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; //抢占优先级2,
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2; //子优先级2
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能外部中断通道
NVIC_Init(&NVIC_InitStructure);
}
  1. 中断程序

    这里的功能是当按键触发后切换led的状态
//外部中断2服务程序
void EXTI0_IRQHandler(void)
{
Delay(100);//消抖
if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0)==1) //检测按键
{
if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_12)==1) //检测led灯的状态,进行切换
{
GPIO_ResetBits(GPIOB,GPIO_Pin_12);
}else{
GPIO_SetBits(GPIOB,GPIO_Pin_12);
} } EXTI_ClearITPendingBit(EXTI_Line0); //清除LINE0上的中断标志位 }

注意:配置中断函数时,先确保提供的头文件中有相应的中断函数,否则会报错



六、程序源码

main.c 文件

#include "stm32f10x.h"
#include "stm32f10x_exti.h"
#include "misc.h" /*************** 配置LED用到的I/O口 *******************/
void LED_GPIO_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB, ENABLE); // 使能PC端口时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12; //选择对应的引脚
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure); //初始化PC端口
GPIO_SetBits(GPIOB, GPIO_Pin_12 ); // 关闭LED
} void Delay(__IO u32 nCount)
{
for(; nCount != 0; nCount--);
} //将GPIOA_0设置为下拉输入
void KEY_Init(void) //IO初始化
{
GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); //使能PORTB,PORTE时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE); //使能AFIO复用功能时钟 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; // 0 pin
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; // 设置成下拉输入
GPIO_Init(GPIOA, &GPIO_InitStructure); // 初始化GPIOA_0 } /* 配置PA0为外部中断 */
void EXTIX_Init(void)
{
EXTI_InitTypeDef EXTI_InitStructure; GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource0); // 选择GPIOA_0作为中断EXTI0的线路 EXTI_InitStructure.EXTI_Line=EXTI_Line0; //中断/事件线
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; // 中断触发
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising; // 下降沿触发
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure); //根据EXTI_InitStruct中指定的参数初始化外设EXTI寄存器
} //初始化中断
void NVICX_Init(void)
{
NVIC_InitTypeDef NVIC_InitStructure; NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn; //使能按键WK_UP所在的外部中断通道
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; //抢占优先级2,
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2; //子优先级2
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能外部中断通道
NVIC_Init(&NVIC_InitStructure);
} //外部中断2服务程序
void EXTI0_IRQHandler(void)
{
Delay(100);//消抖
if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0)==1) //WK_UP按键
{
if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_12)==1)
{
GPIO_ResetBits(GPIOB,GPIO_Pin_12);
}else{
GPIO_SetBits(GPIOB,GPIO_Pin_12);
} } EXTI_ClearITPendingBit(EXTI_Line0); //清除LINE0上的中断标志位 } int main(void)
{
SystemInit();
LED_GPIO_Config(); //LED 端口初始化
KEY_Init();
EXTIX_Init();
NVICX_Init();
while (1)
{ } }

七、编译运行



编译完成后下载程序并观察运行现象,当GPIOA_0引脚接地一次,LED灯的状态便切换一次

参考文献

STM32系统学习——EXTI(外部中断):https://blog.csdn.net/zxh1592000/article/details/80280715

STM32之EXTI——外部中断:https://www.cnblogs.com/alvis-jing/p/3678285.html

STM32 EXTI(外部中断)的更多相关文章

  1. STM32之EXTI——外部中断

    互联网的广大网友,大家早上中午晚上好.EXTI...故名思义..EX表外,出..I表示Intrrupt..所以合起来就是外部中断...说到这..我觉得我最近的六级水平(背单词)又进了一步,稍微自夸了下 ...

  2. STM32之外部中断控制

    一.STM32外部中断 1.STM32外部中断结构图 如上图所示:主要包括四个环节,GPIO.AFIO.EXTI.NVIC.以STM32F103VE(100脚)为例说明硬件模块的数量: GPIO:   ...

  3. STM32的外部中断配置及使用

    STM32的外部中断配置及使用 配置1:GPIO: 配置外部中断为输入模式: 配置2:EXTI: 配置外部中断线和触发模式: 配置3:NVIC: 配置外部中断源和中断优先级: 需要注意的是:RCC_A ...

  4. 第17章 EXTI—外部中断/事件控制器

    第17章     EXTI—外部中断/事件控制器 全套200集视频教程和1000页PDF教程请到秉火论坛下载:www.firebbs.cn 野火视频教程优酷观看网址:http://i.youku.co ...

  5. 第17章 EXTI—外部中断/事件控制器—零死角玩转STM32-F429系列

    第17章     EXTI—外部中断/事件控制器 全套200集视频教程和1000页PDF教程请到秉火论坛下载:www.firebbs.cn 野火视频教程优酷观看网址:http://i.youku.co ...

  6. STM32 GPIO外部中断总结

    一.STM32中断分组: STM32 的每一个GPIO都能配置成一个外部中断触发源,这点也是 STM32 的强大之处.STM32 通过根据引脚的序号不同将众多中断触发源分成不同的组,比如:PA0,PB ...

  7. EXTI—外部中断/事件控制器

    外部中断/事件控制器(EXTI)管理了控制器的 23 个中断/事件线.每个中断/事件线都对应有一个边沿检测器,可以实现输入信号的上升沿检测和下降沿的检测. EXTI 可以实现对每个中断/事件线进行单独 ...

  8. 浅谈stm32的外部中断

    简述 本文简单介绍stm32外部中断的一般操作步骤,后续会补充外部中断的相关内容 stm32的中断控制器支持19个外部中断/事件请求: line0~line15:这16条line分别对应不同GPIO口 ...

  9. STM32之外部中断

    图1.0 图1.1 中断控制器支持23条中断线,其中16条是IO管脚中断线,分别是EXTI0~EXTI15:  图 1.2 另外七根中断线如下图: 中断线和管脚的对应关系:EXTI0~EXTI15 和 ...

随机推荐

  1. aha

    欢迎使用 MWeb MWeb 是专业的 Markdown 写作.记笔记.静态博客生成软件,目前已支持 Mac,iPad 和 iPhone.MWeb 有以下特色: 软件本身: 使用原生的 macOS 技 ...

  2. CF1547A Shortest Path with Obstacle 题解

    Content 给定两个在二维平面上的网格 \(A(x_A,y_A)\) 和 \(B(x_B,y_B)\),另外,还有一个不可通过的网格 \(F(x_F,y_F)\).你需要求出在不经过 \(F\) ...

  3. 【嵌入式AI】全志 XR806 OpenHarmony 鸿蒙系统固件烧录

      欢迎关注我的公众号 [极智视界],回复001获取Google编程规范   O_o   >_<   o_O   O_o   ~_~   o_O   大家好,我是极智视界,本教程详细记录了 ...

  4. java 编程基础 反射方式获取泛型的类型Fileld.getGenericType() 或Method.getGenericParameterTypes(); (ParameterizedType) ;getActualTypeArguments()

    引言 自从JDK5以后,Java Class类增加了泛型功能,从而允许使用泛型来限制Class类,例如,String.class的类型实际上是 Class 如果 Class 对应的类暂时未知,则使 C ...

  5. 小白误入(<<<绝没有针对>>>)企业级架构介绍与IP tables防火墙介绍

    内容详细 架构图 架构图详解 架构: 把一个整体(完成人类生存的所有工作)切分成不同的部分(分工),由不同角色来完成这些分工,并通过建立不同部分相互沟通的机制,使得这些部分能够有机的结合为一个整体,并 ...

  6. 使用iframe内嵌PC网站实现高度自适应

    加个样式 <style> iframe { display: block; border: none; height: 90vh;/*设置高度百分比,一直调到只有一个滚动调为止*/ wid ...

  7. JAVA获取当前年份,月份、日期、小时、分钟、秒等

    import java.util.Calendar; public class Main { public static void main(String[] args) { Calendar cal ...

  8. JAVA使用itext根据模板生成PDF文档

    1.制作PDF模板 网址打开:https://www.pdfescape.com/open/ 我们这里先在线上把基础的内容用word文档做好,然后转成PDF模板,直接上传到网站上,这样方便点 假设我们 ...

  9. JAVA判断IP是否是内网IP

    /** * 私有IP: * A类  10.0.0.0-10.255.255.255   * B类  172.16.0.0-172.31.255.255   * C类  192.168.0.0-192. ...

  10. 【LeetCode】232. Implement Queue using Stacks 解题报告(Python & Java)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 Python解法 Java解法 日期 [LeetCo ...