STM32 EXTI(外部中断)
一、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 寄存器
中断屏蔽寄存器(EXTI_IMR)
事件屏蔽寄存器(EXTI_EMR)
上升沿触发选择寄存器(EXTI_RTSR)
注意: 外部唤醒线是边沿触发的,这些线上不能出现毛刺信号。在写EXTI_RTSR寄存器时,在外部中断线上的上升沿信号不能被识别,挂起位也不会被置位。在同一中断线上,可以同时设置上升沿和下降沿触发。即任一边沿都可触发中断下降沿触发选择寄存器(EXTI_FTSR)
注意: 外部唤醒线是边沿触发的,这些线上不能出现毛刺信号。在写EXTI_FTSR寄存器时,在外部中断线上的下降沿信号不能被识别,挂起位不会被置位。在同一中断线上,可以同时设置上升沿和下降沿触发。即任一边沿都可触发中断。软件中断事件寄存器(EXTI_SWIER)
挂起寄存器(EXTI_PR)
外部中断/事件寄存器映像
五、EXTI 程序分析
- EXTI 初始化程序的结构体
typedef struct
{
uint32_t EXTI_Line; // 中断/事件线
EXTIMode_TypeDef EXTI_Mode; // EXTI 模式
EXTITrigger_TypeDef EXTI_Trigger; // 触发类型
FunctionalState EXTI_LineCmd; // EXTI 使能
}EXTI_InitTypeDef;
- 初始化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
}
- 初始化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寄存器
}
- 配置 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);
}
- 中断程序
这里的功能是当按键触发后切换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(外部中断)的更多相关文章
- STM32之EXTI——外部中断
互联网的广大网友,大家早上中午晚上好.EXTI...故名思义..EX表外,出..I表示Intrrupt..所以合起来就是外部中断...说到这..我觉得我最近的六级水平(背单词)又进了一步,稍微自夸了下 ...
- STM32之外部中断控制
一.STM32外部中断 1.STM32外部中断结构图 如上图所示:主要包括四个环节,GPIO.AFIO.EXTI.NVIC.以STM32F103VE(100脚)为例说明硬件模块的数量: GPIO: ...
- STM32的外部中断配置及使用
STM32的外部中断配置及使用 配置1:GPIO: 配置外部中断为输入模式: 配置2:EXTI: 配置外部中断线和触发模式: 配置3:NVIC: 配置外部中断源和中断优先级: 需要注意的是:RCC_A ...
- 第17章 EXTI—外部中断/事件控制器
第17章 EXTI—外部中断/事件控制器 全套200集视频教程和1000页PDF教程请到秉火论坛下载:www.firebbs.cn 野火视频教程优酷观看网址:http://i.youku.co ...
- 第17章 EXTI—外部中断/事件控制器—零死角玩转STM32-F429系列
第17章 EXTI—外部中断/事件控制器 全套200集视频教程和1000页PDF教程请到秉火论坛下载:www.firebbs.cn 野火视频教程优酷观看网址:http://i.youku.co ...
- STM32 GPIO外部中断总结
一.STM32中断分组: STM32 的每一个GPIO都能配置成一个外部中断触发源,这点也是 STM32 的强大之处.STM32 通过根据引脚的序号不同将众多中断触发源分成不同的组,比如:PA0,PB ...
- EXTI—外部中断/事件控制器
外部中断/事件控制器(EXTI)管理了控制器的 23 个中断/事件线.每个中断/事件线都对应有一个边沿检测器,可以实现输入信号的上升沿检测和下降沿的检测. EXTI 可以实现对每个中断/事件线进行单独 ...
- 浅谈stm32的外部中断
简述 本文简单介绍stm32外部中断的一般操作步骤,后续会补充外部中断的相关内容 stm32的中断控制器支持19个外部中断/事件请求: line0~line15:这16条line分别对应不同GPIO口 ...
- STM32之外部中断
图1.0 图1.1 中断控制器支持23条中断线,其中16条是IO管脚中断线,分别是EXTI0~EXTI15: 图 1.2 另外七根中断线如下图: 中断线和管脚的对应关系:EXTI0~EXTI15 和 ...
随机推荐
- aha
欢迎使用 MWeb MWeb 是专业的 Markdown 写作.记笔记.静态博客生成软件,目前已支持 Mac,iPad 和 iPhone.MWeb 有以下特色: 软件本身: 使用原生的 macOS 技 ...
- CF1547A Shortest Path with Obstacle 题解
Content 给定两个在二维平面上的网格 \(A(x_A,y_A)\) 和 \(B(x_B,y_B)\),另外,还有一个不可通过的网格 \(F(x_F,y_F)\).你需要求出在不经过 \(F\) ...
- 【嵌入式AI】全志 XR806 OpenHarmony 鸿蒙系统固件烧录
欢迎关注我的公众号 [极智视界],回复001获取Google编程规范 O_o >_< o_O O_o ~_~ o_O 大家好,我是极智视界,本教程详细记录了 ...
- java 编程基础 反射方式获取泛型的类型Fileld.getGenericType() 或Method.getGenericParameterTypes(); (ParameterizedType) ;getActualTypeArguments()
引言 自从JDK5以后,Java Class类增加了泛型功能,从而允许使用泛型来限制Class类,例如,String.class的类型实际上是 Class 如果 Class 对应的类暂时未知,则使 C ...
- 小白误入(<<<绝没有针对>>>)企业级架构介绍与IP tables防火墙介绍
内容详细 架构图 架构图详解 架构: 把一个整体(完成人类生存的所有工作)切分成不同的部分(分工),由不同角色来完成这些分工,并通过建立不同部分相互沟通的机制,使得这些部分能够有机的结合为一个整体,并 ...
- 使用iframe内嵌PC网站实现高度自适应
加个样式 <style> iframe { display: block; border: none; height: 90vh;/*设置高度百分比,一直调到只有一个滚动调为止*/ wid ...
- JAVA获取当前年份,月份、日期、小时、分钟、秒等
import java.util.Calendar; public class Main { public static void main(String[] args) { Calendar cal ...
- JAVA使用itext根据模板生成PDF文档
1.制作PDF模板 网址打开:https://www.pdfescape.com/open/ 我们这里先在线上把基础的内容用word文档做好,然后转成PDF模板,直接上传到网站上,这样方便点 假设我们 ...
- 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. ...
- 【LeetCode】232. Implement Queue using Stacks 解题报告(Python & Java)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 Python解法 Java解法 日期 [LeetCo ...