你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【经验分享】STM32-外部中断详解

[复制链接]
STMCU小助手 发布时间:2022-5-6 11:14
前言
本章讲解STM32的另一个重要的外设资源——外部中断;在前面已经讲过了NVIC中断优先级管理,相信大家对STM32的中断系统有了初步的了解,知道了如何给每一个内部的中断设置顺序,然而只有内部外设的中断信号还不够,有时候我们要监视外部的数据信号变化,这就需要外部中断了。

一、外部中断是什么?
首先我们要理解什么是中断。

想象一个场景:你在家里看书学习,这时候突然来电话了。你的做法是停止学习去接电话,电话打完再放下电话继续学习。这一个过程就体现了中断的思想。我们抽象一下,把自己想象成一个单片机系统,看书就是正在执行的主任务,如果没有外界干扰,这个系统会一直执行当前的主任务。而当外部有改变(电话响了)的时候,系统会第一时间响应,从主任务跳转到这个紧急任务中,这个突发的事件就是(外部)中断,而系统处理的紧急任务则是中断处理函数。当紧急任务(接电话)完毕之后,系统又会回到最初的主任务中。

这就是MCU的外部中断过程。

二、STM32外部中断概述
1. STM32的外部中断线

STM32的每个IO都可以作为外部中断输入。
STM32的中断控制器支持19个外部中断/事件请求:
线0~15:对应外部IO口的输入中断。

线16:连接到PVD输出。

线17:连接到RTC闹钟事件。

线18:连接到USB唤醒事件。

每个外部中断线可以独立的配置触发方式(上升沿,下降沿或者双边沿触发),触发/屏蔽,专用的状态位。

2. 外部中断线与IO引脚对应关系      
        这时候想必读者可能要问了,STM32供IO使用的中断线只有16个,但是STM32F10x系列的IO口多达上百个,STM32F103ZET6(112),STM32F103RCT6(51),那么中断线怎么跟IO口对应上呢?下图就是STM32的外部中断线和IO口的对应关系:

NU8(QL}MD49`]QMQX}OI`YB.png

         对于每个中断线,我们可以设置相应的触发方式(上升沿触发,下降沿触发,边沿触发)以及使能。

3. 中断向量与服务函数

是不是16个中断线就可以分配16个中断服务函数呢?

IO口外部中断在中断向量表中只分配了7个中断向量,也就是只能使用7个中断服务函数

0INPN35(%P{J]G73VLSZ(E0.png

从表中可以看出,外部中断线5~9分配一个中断向量,共用一个服务函数 外部中断线10~15分配一个中断向量,共用一个中断服务函数。
下面是中断服务函数列表:

EXTI0_IRQHandler         

EXTI1_IRQHandler

EXTI2_IRQHandler         

EXTI3_IRQHandler         

EXTI4_IRQHandler         

EXTI9_5_IRQHandler        

EXTI15_10_IRQHandler      

三、STM32外部中断库函数配置
1. 常用库函数

①void GPIO_EXTILineConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource);

   //设置IO口与中断线的映射关系

   exp:  GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource2);

②void EXTI_Init(EXTI_InitTypeDef* EXTI_InitStruct);

//初始化中断线:触发方式等

③ITStatus EXTI_GetITStatus(uint32_t EXTI_Line);

//判断中断线中断状态,是否发生

④void EXTI_ClearITPendingBit(uint32_t EXTI_Line);

//清除中断线上的中断标志位

以上这四个函数是配置外部中断常用的库函数,第一个函数很好理解,就是配置IO口与中断线的映射关系的。我们重点讲解第二个函数:

EXTI_Init函数:
void EXTI_Init(EXTI_InitTypeDef* EXTI_InitStruct);

其结构体成员变量如下:

  1. typedef struct
  2. {
  3.   uint32_t EXTI_Line;   //指定要配置的中断线           
  4.   EXTIMode_TypeDef EXTI_Mode;   //模式:事件 OR中断
  5.   EXTITrigger_TypeDef EXTI_Trigger;//触发方式:上升沿/下降沿/双沿触发
  6.   FunctionalState EXTI_LineCmd;  //使能 OR失能
  7. }EXTI_InitTypeDef;

  8. //实例:
  9. // EXTI_InitStructure.EXTI_Line=EXTI_Line2;         
  10. // EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;        
  11. // EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
  12. // EXTI_InitStructure.EXTI_LineCmd = ENABLE;
  13. // EXTI_Init(&EXTI_InitStructure);
复制代码

可见由四部分组成,分别是中短线、中断模式(事件或者中断)、触发方式(上升沿、下降沿或者双边沿触发)以及使能位。

2. 库函数配置一般步骤
①初始化IO口为输入。
       GPIO_Init();

②开启IO口复用时钟。

       RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);

③设置IO口与中断线的映射关系。
        void GPIO_EXTILineConfig();

④初始化线上中断,设置触发条件等。
       EXTI_Init();

⑤配置中断分组(NVIC),并使能中断。
       NVIC_Init();

⑥编写中断服务函数。

      EXTIx_IRQHandler();

⑦清除中断标志位
      EXTI_ClearITPendingBit();

下面是配置外部中断的代码,其实现的功能是通过STM32单片机的外部中断0来捕获按键的电平变化,使按键按下时LED灯反转,按键和LED的源文件在前面的GPIO那一章有讲解。

  1. //exti.c源文件
  2. #include "exti.h"
  3. #include "led.h"
  4. #include "key.h"
  5. #include "delay.h"

  6. //外部中断0服务程序
  7. void EXTIX_Init(void)
  8. {
  9.         EXTI_InitTypeDef EXTI_InitStruct;
  10.         NVIC_InitTypeDef NVIC_InitStruct;
  11.         
  12.   KEY_Init();
  13.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
  14.         
  15.         GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource4);
  16.         
  17.         EXTI_InitStruct.EXTI_Line=EXTI_Line4;
  18.         EXTI_InitStruct.EXTI_LineCmd=ENABLE;
  19.         EXTI_InitStruct.EXTI_Mode=EXTI_Mode_Interrupt;
  20.         EXTI_InitStruct.EXTI_Trigger=EXTI_Trigger_Falling;
  21.         
  22.         EXTI_Init(&EXTI_InitStruct);
  23.         
  24.         NVIC_InitStruct.NVIC_IRQChannel=EXTI4_IRQn;
  25.         NVIC_InitStruct.NVIC_IRQChannelCmd =ENABLE;
  26.         NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority =2;
  27.         NVIC_InitStruct.NVIC_IRQChannelSubPriority =2;
  28.         
  29.         NVIC_Init(&NVIC_InitStruct);
  30. }
  31. void EXTI4_IRQHandler(void)
  32. {
  33.         delay_ms(10);
  34.         if(KEY0){
  35.                 LED0=!LED0;
  36.                 LED1=!LED1;
  37.         }
  38.         EXTI_ClearFlag(EXTI_Line4);
  39. }
复制代码
  1. //exti.h头文件

  2. #ifndef __EXTI_H
  3. #define __EXIT_H         
  4. #include "sys.h"

  5. void EXTIX_Init(void);//外部中断初始化                                                            
  6. #endif
复制代码
  1. //main.c源文件

  2. #include "led.h"
  3. #include "delay.h"
  4. #include "key.h"
  5. #include "sys.h"
  6. #include "usart.h"
  7. #include "exti.h"

  8. int main(void)
  9. {               
  10.   int i=0;
  11.         delay_init();                     //延时函数初始化         
  12.         NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
  13.         uart_init(115200);         //串口初始化为115200
  14.          LED_Init();                                  //初始化与LED连接的硬件接口
  15.         KEY_Init();                 //初始化与按键连接的硬件接口
  16.         EXTIX_Init();                         //外部中断初始化
  17.         LED0=0;                                        //点亮LED0
  18.         while(1)
  19.         {            
  20.                 printf("%d\r\n",i);        
  21.                 delay_ms(5000);        
  22.     i++;               
  23.         }
  24. }




复制代码

总结
本章讲解的是STM32的外部中断,通过外部中断的原理、STM32外部中断概述以及外部中断库函数配置流程来详细讲述了STM32的外部中断这一外设,希望读者能够认真学习。
收藏 评论0 发布时间:2022-5-6 11:14

举报

0个回答

所属标签

相似分享

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版