【STM32】EXTI---外部中断/事件控制器

举报
AXYZdong 发表于 2022/01/15 16:44:38 2022/01/15
【摘要】 EXTI——外部中断/事件控制器。外部中断简介,EXTI初始化结构体,外部中断控制实验。利用按键输入作为中断的外部输入,产生中断后,进入中断服务函数,实现LED状态的变化。

Author:AXYZdong 自动化专业 工科男
有一点思考,有一点想法,有一点理性!
定个小小目标,努力成为习惯!在最美的年华遇见更好的自己!



  • 开发板:stm32f407VET6
  • 开发环境:keil5 MDK

一、EXTI 简介

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


二、EXTI 功能框图


image.png

  • 信号线上斜杠并标注 “23” 字样 :表示在控制器内部类似的信号线路有23个。
  • EXTI 是挂靠在 APB2 总线上的。

三、中断/事件线


中断/事件线 输入源
EXTI0 PX0(X 可为 A,B,C,D,E,F,G,H,I)
EXTI1 PX1(X 可为 A,B,C,D,E,F,G,H,I)
EXTI2 PX2(X 可为 A,B,C,D,E,F,G,H,I)
EXTI3 PX3(X 可为 A,B,C,D,E,F,G,H,I)
EXTI4 PX4(X 可为 A,B,C,D,E,F,G,H,I)
EXTI5 PX5(X 可为 A,B,C,D,E,F,G,H,I)
EXTI6 PX6(X 可为 A,B,C,D,E,F,G,H,I)
EXTI7 PX7(X 可为 A,B,C,D,E,F,G,H,I)
EXTI8 PX8(X 可为 A,B,C,D,E,F,G,H,I)
EXTI9 PX9(X 可为 A,B,C,D,E,F,G,H,I)
EXTI10 PX10(X 可为 A,B,C,D,E,F,G,H,I)
EXTI11 PX11(X 可为 A,B,C,D,E,F,G,H,I)
EXTI12 PX12(X 可为 A,B,C,D,E,F,G,H,I)
EXTI13 PX13(X 可为 A,B,C,D,E,F,G,H,I)
EXTI14 PX14(X 可为 A,B,C,D,E,F,G,H,I)
EXTI15 PX15(X 可为 A,B,C,D,E,F,G,H,I)
EXTI16 可编程电压检测器(PVD)输出
EXTI17 RTC 闹钟事件
EXTI18 USB OTG FS 唤醒事件
EXTI19 以太网唤醒事件
EXTI20 USB OTG HS(在 FS 中配置)唤醒事件
EXTI21 RTC 入侵和时间戳事件
EXTI22 RTC 唤醒事件

  • EXTI0至 EXTI15用于 GPIO,通过编程控制可以实现任意一个 GPIO作为EXTI 的输入源
  • SYSCFG 外部中断配置寄存器 1 配置EXTI0

image.png

▲ EXTI0输入源选择


四、EXTI 初始化结构体

typedef struct
{
   //中断/事件线
  uint32_t EXTI_Line;               /*!< Specifies the EXTI lines to be enabled or disabled.
                                         This parameter can be any combination value of @ref EXTI_Lines */
   //EXTI 模式
  EXTIMode_TypeDef EXTI_Mode;       /*!< Specifies the mode for the EXTI lines.
                                         This parameter can be a value of @ref EXTIMode_TypeDef */
   //触发类型
  EXTITrigger_TypeDef EXTI_Trigger; /*!< Specifies the trigger signal active edge for the EXTI lines.
                                         This parameter can be a value of @ref EXTITrigger_TypeDef */
   //EXTI 控制
  FunctionalState EXTI_LineCmd;     /*!< Specifies the new state of the selected EXTI lines.
                                         This parameter can be set either to ENABLE or DISABLE */ 
}EXTI_InitTypeDef;

4.1. 中断/事件线

#define EXTI_Line0       ((uint32_t)0x00001)     /*!< External interrupt line 0 */
#define EXTI_Line1       ((uint32_t)0x00002)     /*!< External interrupt line 1 */
#define EXTI_Line2       ((uint32_t)0x00004)     /*!< External interrupt line 2 */
#define EXTI_Line3       ((uint32_t)0x00008)     /*!< External interrupt line 3 */
#define EXTI_Line4       ((uint32_t)0x00010)     /*!< External interrupt line 4 */
#define EXTI_Line5       ((uint32_t)0x00020)     /*!< External interrupt line 5 */
#define EXTI_Line6       ((uint32_t)0x00040)     /*!< External interrupt line 6 */
#define EXTI_Line7       ((uint32_t)0x00080)     /*!< External interrupt line 7 */
#define EXTI_Line8       ((uint32_t)0x00100)     /*!< External interrupt line 8 */
#define EXTI_Line9       ((uint32_t)0x00200)     /*!< External interrupt line 9 */
#define EXTI_Line10      ((uint32_t)0x00400)     /*!< External interrupt line 10 */
#define EXTI_Line11      ((uint32_t)0x00800)     /*!< External interrupt line 11 */
#define EXTI_Line12      ((uint32_t)0x01000)     /*!< External interrupt line 12 */
#define EXTI_Line13      ((uint32_t)0x02000)     /*!< External interrupt line 13 */
#define EXTI_Line14      ((uint32_t)0x04000)     /*!< External interrupt line 14 */
#define EXTI_Line15      ((uint32_t)0x08000)     /*!< External interrupt line 15 */
#define EXTI_Line16      ((uint32_t)0x10000)     /*!< External interrupt line 16 Connected to the PVD Output */
#define EXTI_Line17      ((uint32_t)0x20000)     /*!< External interrupt line 17 Connected to the RTC Alarm event */
#define EXTI_Line18      ((uint32_t)0x40000)     /*!< External interrupt line 18 Connected to the USB OTG FS Wakeup from suspend event */                                    
#define EXTI_Line19      ((uint32_t)0x80000)     /*!< External interrupt line 19 Connected to the Ethernet Wakeup event */
#define EXTI_Line20      ((uint32_t)0x00100000)  /*!< External interrupt line 20 Connected to the USB OTG HS (configured in FS) Wakeup event  */
#define EXTI_Line21      ((uint32_t)0x00200000)  /*!< External interrupt line 21 Connected to the RTC Tamper and Time Stamp events */                                               
#define EXTI_Line22      ((uint32_t)0x00400000)  /*!< External interrupt line 22 Connected to the RTC Wakeup event */ 

4.2. EXTI 模式

typedef enum
{
  EXTI_Mode_Interrupt = 0x00,  //产生中断
  EXTI_Mode_Event = 0x04       //产生事件
}EXTIMode_TypeDef;

4.3. 触发类型

typedef enum
{
  EXTI_Trigger_Rising = 0x08,         //上升沿
  EXTI_Trigger_Falling = 0x0C,        //下降沿
  EXTI_Trigger_Rising_Falling = 0x10  //上升沿和下降沿都触发
}EXTITrigger_TypeDef;

4.4. EXTI 控制

使能 EXTI ,一般都是使能,ENABLE

五、外部中断控制实验

按键作为外部输入,按下按键触发外部中断,进入中断服务函数。

编程要点

  • 初始化LED的GPIO
  • 开启按键GPIO时钟和SYSCFG时钟
  • 配置按键GPIO为输入模式
  • 配置NVIC
  • 按键GPIO连接到EXTI输入
  • 配置EXTI中断/事件线
  • EXTI中断服务函数

EXTI.h

// =============================================
# @Time    : 2020-10-09
# @Author  : AXYZdong
# @FileName: exti.h
# @Software: keil5 MDK
// =============================================

#ifndef _EXTI_H
#define _EXTI_H

//引脚宏定义  
/*******************************************************/ 
#define KEY1_EXTI_PORTSOURCE   EXTI_PortSourceGPIOE
#define KEY1_EXTI_PINSOURCE    EXTI_PinSource3
#define KEY1_EXTI_LINE         EXTI_Line3
#define KEY1_EXTI_IRQ          EXTI3_IRQn

#define KET1_IRQHandler        EXTI3_IRQHandler

void EXTI_Config(void);

#endif

EXTI.c

// =============================================
# @Time    : 2020-10-09
# @Author  : AXYZdong
# @FileName: EXTI.c
# @Software: keil5 MDK
// =============================================

#include "stm32f4xx.h"
#include "exti.h"
#include "bsp_key.h"
#include "delay.h"

uint8_t flag = 0x00;
void EXTI_Config(void)
{	
	EXTI_InitTypeDef EXTI_InitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;
	
	/* 使能 SYSCFG 时钟 ,使用 GPIO 外部中断时必须使能 SYSCFG 时钟*/
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
	
  /* 连接 EXTI 中断源 到 key1 引脚 */ 	
	SYSCFG_EXTILineConfig(KEY1_EXTI_PORTSOURCE, KEY1_EXTI_PINSOURCE);
	
	EXTI_InitStructure.EXTI_Line = KEY1_EXTI_LINE;          //连接中断源
	EXTI_InitStructure.EXTI_LineCmd = ENABLE;               //使能中断
	EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;     //中断模式
	EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; //下降沿触发
	EXTI_Init(&EXTI_InitStructure);
	
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
	NVIC_InitStructure.NVIC_IRQChannel = KEY1_EXTI_IRQ;      //中断通道
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1;  //抢占优先级1
	NVIC_InitStructure.NVIC_IRQChannelSubPriority =1;		 //子优先级1
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;			 //IRQ通道使能
	NVIC_Init(&NVIC_InitStructure);	                         //根据指定的参数初始化VIC寄存器
	
}

void KET1_IRQHandler(void)
{
  delay_ms(10);
	if(KEY1 == RESET)
	{
	  flag++;
		flag &= 0x01;
		flag == RESET ? GPIO_SetBits(GPIOA,GPIO_Pin_6) : GPIO_ResetBits(GPIOA,GPIO_Pin_6);
	}
	while(!KEY1);
	EXTI_ClearITPendingBit(KEY1_EXTI_LINE);
}

main.c

// =============================================
# @Time    : 2020-10-09
# @Author  : AXYZdong
# @FileName: main.c
# @Software: keil5 MDK
// =============================================

#include "stm32f4xx.h"
#include "bsp_led.h"
#include "bsp_key.h"
#include "sys.h"
#include "delay.h"
#include "exti.h"

int main()
{ 
 	delay_init(168);        //初始化延时函数
	LED_GPIO_Config();      //初始化LED端口 
 	KEY_Init();             //初始化与按键连接的硬件接口
	EXTI_Config();          //初始化外部中断
	while(1)
	{
	}
}

实验现象

按下 KEY1 并弹开,LED点亮。再按下 KEY1 并弹开,LED熄灭。

六、总结

  • 注意 .h 文件中 EXTI 中断/事件线的配置
  • 与 f103 不同,f407需要开启 SYSCFG 外部中断配置寄存器的时钟
  • 宏定义的使用可以便于代码移植

【参考文献】

[1] 《零死角玩转 STM32—基于野火 F407[霸天虎]开发板 》


  本次的分享就到这里


11

好书不厌百回读,熟读自知其中意。将学习成为习惯,用知识改变命运,用博客见证成长,用行动证明努力。
如果我的博客对你有帮助、如果你喜欢我的博客内容,请 “点赞” “评论” “收藏” 一键三连哦!
听说 👉 点赞 👈 的人运气不会太差,每一天都会元气满满呦!^ _ ^
**码字不易,大家的支持就是我坚持下去的动力。点赞后不要忘了👉关注👈我哦!


如果以上内容有任何错误或者不准确的地方,欢迎在下面👇留个言。或者你有更好的想法,欢迎一起交流学习~~~

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。