当前位置:   article > 正文

STM32外部中断EXTI介绍及配置(标准库)详解_在stm32上配置外部中断时需要注意什么

在stm32上配置外部中断时需要注意什么

什么是中断

在主程序运行的过程中,出现了特定的中断触发条件,使CPU暂停当前的运行程序,转而去处理中断程序,处理完成后又返回原来被暂停的位置继续运行。

STM32有68个可屏蔽中断通道(不包含16个Cortex™-M3的中断线),16个可编程的优先等级(使用了4位中断优先级)(可以对优先级进行分组,设置抢占优先级和响应优先级),使用NVIC(嵌套向量中断控制器)进行统一管理。

STM32外部中断示意图简介

介绍为从右往左

NVIC套向量中断控制器

内核外设,进行中断优先级分配

NVIC有多个输入口,可以接入多个外设

一个外设可能会同时占用多个中断通道,所以有n条线进行连接

NVIC只有一个输出口,根据中断优先级向CPU输出当前该处理的中断

NVIC优先级分组

NVIC的中断优先级由优先级寄存器的4位(0-15)决定,分为高n位的抢占优先级和低4-n位的响应优先级。分组位数取值为2的0-4次方。

抢占优先级高的可以打断别的程序中断,优先进行自己的中断。也就是中断嵌套。

响应优先级高的,可以在别人的中断后面进行排队。vip插队,但不能打断正在进行的中断程序,只能排在下一位。

抢占优先级和响应优先级为同级关系,按优先级号进行优先中断,数值越小优先级越高,0为最高优先级。如果抢占优先级和响应优先级的优先等级相同,则看中断号排队,可以参考STM32中断中的向量表。

EXTI外部中断

简介

EXTI可以监测指定GPIO口的电平信号,当指定的GPIO口的电平信号发生改变的时候,EXTI立即向NVIC发送中断申请,经过NVIC裁决后中断CPU主程序执行EXTI中断程序。

触发方式:上升沿、下降沿、软件触发

支持的GPIO口:所有的GPIO口,但相同的Pin不能同时触发中断
例如:PA0和PB0只能触发其中的一个,如下图,共有16个外部中断线路,下图只截取了其中一个共16个。

通道数:EXTI支持20个中断和时间屏蔽位

下图中,GPIO端口连接到16个外部中断/事件线上;EXTI0 — EXTI15;外加PVD电源电压检测、RTC闹钟、USB唤醒和以太网唤醒四个蹭网设备并联接入ETIO,可参考整体结构图。

响应方式:中断响应(触发中断)和事件响应(不触发中断触发其他外设,ADC等)

 外部中断整体结构图

要注意EXTI0-EXTI4每个都有一个单独的中断函数。

EXTI9_5和EXTI15-10分别在一个数据通道中,执行中断时需要判断是哪个引脚触发的中断。

触发其他外设为事件响应,有20条通道。

EXTI内部框图

 

 

AFIO数据选择器

在GPIOx的16个引脚里选择其中一个连接到后面的EXTI的通道里。所以相同的Pin不能同时触发中断。

AFIO主要用于引脚复用功能的选择和重定义

在STM32中AFIO主要完成两个任务:复用功能引脚重映射、中断引脚选择。

一个引脚可以有多个功能为复用,有些引脚的功能可以映射到其他引脚进行使用(感觉有点像fate里的投影)。

AFIO选择中断引脚结构图

STM32外部中断配置 

配置中断整体结构框图中的外设即可

中断服务映射关系

 表格来源STM32 外部中断详解(原理+配置代码)_stm32外部中断代码-CSDN博客

配置流程

1.配置RCC         打开涉及到外设的时钟

2.配置GPIO        端口为输入模式

3.配置AFIO

4.配置EXTI        边沿触发方式选择以及触发响应方式,中断or事件

5.配置NVIC        选择合适优先级

RCC时钟配置

内核外设不用开启时钟

  1. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);//开启GPIOB的时钟
  2. RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);//开启AFIO的时钟

GPIO初始化

EXTI推荐配置为浮空、上拉或下拉

  1. GPIO_InitTypeDef GPIO_InitStructure;
  2. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //上拉输入
  3. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14; //选择14号引脚
  4. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  5. GPIO_Init(GPIOB, &GPIO_InitStructure);

AFIO配置

 AFIO库函数
  1. void GPIO_AFIODeInit(void);//复位
  2. void GPIO_PinLockConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);//锁定配置
  3. //事件输出
  4. void GPIO_EventOutputConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource);
  5. void GPIO_EventOutputCmd(FunctionalState NewState);
  6. void GPIO_PinRemapConfig(uint32_t GPIO_Remap, FunctionalState NewState);//引脚重映射
  7. //配置AFIO数据选择器,选择对应引脚
  8. void GPIO_EXTILineConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource);
  9. void GPIO_ETH_MediaInterfaceConfig(uint32_t GPIO_ETH_MediaInterface);//以太网相关
初始化
  1. //将外部中断的14号线映射到GPIOB,即选择PB14为外部中断引脚
  2. GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource14);

EXTI配置

EXTI库函数
  1. void EXTI_DeInit(void);//复位
  2. void EXTI_Init(EXTI_InitTypeDef* EXTI_InitStruct);//通过结构体配置,类似GPIO
  3. void EXTI_StructInit(EXTI_InitTypeDef* EXTI_InitStruct);//结构体变量赋值
  4. void EXTI_GenerateSWInterrupt(uint32_t EXTI_Line);//软件触发外部中断
  5. FlagStatus EXTI_GetFlagStatus(uint32_t EXTI_Line);//获取指定标志位是否被置1,主程序使用
  6. void EXTI_ClearFlag(uint32_t EXTI_Line);//清除标志位
  7. ITStatus EXTI_GetITStatus(uint32_t EXTI_Line);//获取指定标志位是否被置1,中断函数中使用
  8. void EXTI_ClearITPendingBit(uint32_t EXTI_Line);//清除标志位
 初始化EXTI
  1. EXTI_InitTypeDef EXTI_InitStructure; //定义结构体变量
  2. EXTI_InitStructure.EXTI_Line = EXTI_Line14; //选择配置外部中断的14号线
  3. EXTI_InitStructure.EXTI_LineCmd = ENABLE; //指定外部中断线使能
  4. EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; //指定外部中断线为中断模式
  5. EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; //指定外部中断线为下降沿触发
  6. EXTI_Init(&EXTI_InitStructure); //配置EXTI外设

 NVIC配置

在misc库文件中

NVIC库函数
  1. void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup);//中断分组
  2. void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct); //设置结构体
  3. void NVIC_SetVectorTable(uint32_t NVIC_VectTab, uint32_t Offset);//设置中断向量表
  4. void NVIC_SystemLPConfig(uint8_t LowPowerMode, FunctionalState NewState);//系统低功耗配置
  5. void SysTick_CLKSourceConfig(uint32_t SysTick_CLKSource);
初始化NVIC
  1. //NVIC中断分组
  2. //此分组配置在整个工程中仅需调用一次
  3. //若有多个中断,可以把此代码放在main函数内,while循环之前
  4. //若调用多次配置分组的代码,则后执行的配置会覆盖先执行的配置
  5. NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //配置NVIC为分组2
  6. NVIC_InitTypeDef NVIC_InitStructure; //定义结构体变量
  7. NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn; //选择配置NVIC的EXTI15_10线
  8. NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //指定NVIC线路使能
  9. NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; //指定NVIC线路的抢占优先级为1
  10. NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; //指定NVIC线路的响应优先级为1
  11. NVIC_Init(&NVIC_InitStructure); //配置NVIC外设

 中断函数

 在启动文件中IRQHeadler结尾的名称

  1. /*
  2. EXTI0_IRQHandler
  3. EXTI1_IRQHandler
  4. EXTI2_IRQHandler
  5. EXTI3_IRQHandler
  6. EXTI4_IRQHandler
  7. EXTI9_5_IRQHandler
  8. EXTI15_10_IRQHandler
  9. */
  10. void EXTI15_10_IRQHandler(void)
  11. {
  12. if (EXTI_GetITStatus(EXTI_Line14) == SET)//判断是否是外部中断14号线触发的中断
  13. {
  14. EXTI_ClearITPendingBit(EXTI_Line14);//清除外部中断14号线的中断标志位
  15. //中断标志位必须清除
  16. //否则中断将连续不断地触发,导致主程序卡死
  17. }
  18. }

写的有点啰嗦,方便自己以后看。

以上为学习江科大老师STM32内容总结,图片来源为老师PPT,仅为个人理解如有不对请指出。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/很楠不爱3/article/detail/676679
推荐阅读
相关标签
  

闽ICP备14008679号