一、基本概念

ARM Coetex-M3内核共支持256个中断,当中16个内部中断,240个外部中断和可编程的256级中断优先级的设置。STM32眼下支持的中断共84个(16个内部+68个外部),还有16级可编程的中断优先级的设置,仅使用中断优先级设置8bit中的高4位。
     STM32可支持68个中断通道,已经固定分配给对应的外部设备,每一个中断通道都具备自己的中断优先级控制字节PRI_n(8位,可是STM32中仅仅使用4位,高4位有效),每4个通道的8位中断优先级控制字构成一个32位的优先级寄存器。68个通道的优先级控制字至少构成17个32位的优先级寄存器。
4bit的中断优先级能够分成2组,从高位看,前面定义的是抢占式优先级,后面是响应优先级。依照这样的分组,4bit一共能够分成5组
第0组:全部4bit用于指定响应优先级;
第1组:最高1位用于指定抢占式优先级,后面3位用于指定响应优先级;
第2组:最高2位用于指定抢占式优先级,后面2位用于指定响应优先级;
第3组:最高3位用于指定抢占式优先级,后面1位用于指定响应优先级;
第4组:全部4位用于指定抢占式优先级。

所谓抢占式优先级和响应优先级,他们之间的关系是:具有高抢占式优先级的中断能够在具有低抢占式优先级的中断处理过程中被响应,即中断嵌套。
     当两个中断源的抢占式优先级同样时,这两个中断将没有嵌套关系,当一个中断到来后,假设正在处理还有一个中断,这个后到来的中断就要等到前一个中断处理完之后才干被处理。假设这两个中断同一时候到达,则中断控制器依据他们的响应优先级高低来决定先处理哪一个;假设他们的抢占式优先级和响应优先级都相等,则依据他们在中断表中的排位顺序决定先处理哪一个。每个中断源都必须定义2个优先级。
有几点须要注意的是:
1)假设指定的抢占式优先级别或响应优先级别超出了选定的优先级分组所限定的范围,将可能得到意想不到的结果;
2)抢占式优先级别同样的中断源之间没有嵌套关系;
3)假设某个中断源被指定为某个抢占式优先级别,又没有其他中断源处于同一个抢占式优先级别,则能够为这个中断源指定随意有效的响应优先级别。
二、 GPIO外部中断
     STM32中,每个GPIO都可以触发一个外部中断,可是,GPIO的中断是以组位一个单位的,同组间的外部中断同一时间仅仅能使用一个。比方说,PA0,PB0,PC0,PD0,PE0,PF0,PG0这些为1组,假设我们使用PA0作为外部中断源,那么别的就不可以再使用了,在此情况下,我们智能使用类似于PB1,PC2这样的末端序号不同的外部中断源。每一组使用一个中断标志EXTIx。EXTI0 – EXTI4这5个外部中断有着自己的单独的中断响应函数,EXTI5-9共用一个中断响应函数,EXTI10-15共用一个中断响应函数。 对于中断的控制,STM32有一个专用的管理机构:NVIC。

三、程序实现

事实上上面那些基本概念和知识仅仅是对STM32的中断系统有一个大概的认识,用程序说话将会更可以加深怎样使用中断。使用外部中断的基本过程例如以下:
1.       设置好对应的时钟;
2.       设置对应的中断;
3.       IO口初始化;
4.       把对应的IO口设置为中断线路(要在设置外部中断之前)并初始化;
5.       在选择的中断通道的响应函数中中断函数。

如果有三个按键,用按键来触发对应的中断。K1/K2/K3连接的是PC5/PC2/PC3,因此我将用EXTI5/EXTI2/EXTI3三个外部中断。PB5/PD6/PD3分别连接了三个LED灯。中断的效果是按下按键,对应的LED灯将会被点亮。

1.       设置对应的时钟
     首先须要打开GPIOB、GPIOC和GPIOE(由于按键另外一端连接的是PE口)。然后由于是要用于触发中断,所以还须要打开GPIO复用的时钟。对应的函数在GPIO的学习笔记中有了具体了解释。具体代码例如以下:
void RCC_cfg()
{
       //打开PE PD PC PBport时钟,而且打开复用时钟
       RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE | RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE);
}
    设置对应的时钟所须要的RCC函数在stm32f10x_rcc.c中,所以要在project中加入此文件。
 
2.       设置好对应的中断
设置对应的中断实际上就是设置NVIC,在STM32的固件库中有一个结构体NVIC_InitTypeDef,里面有对应的标志位设置,然后再用NVIC_Init()函数进行初始化。具体代码例如以下:
void NVIC_cfg()
{
        NVIC_InitTypeDef NVIC_InitStructure;                                              //第一结构体
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);                          //选择中断分组2
       
       
NVIC_InitStructure.NVIC_IRQChannel = EXTI2_IRQChannel;     //选择中断通道2
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //抢占式中断优先级设置为0
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;        //响应式中断优先级设置为0
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                                   //使能中断
        NVIC_Init(&NVIC_InitStructure);
 
       
        NVIC_InitStructure.NVIC_IRQChannel = EXTI3_IRQChannel;            //选择中断通道3
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; //抢占式中断优先级设置为1
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;  //响应式中断优先级设置为1
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                                   //使能中断
        NVIC_Init(&NVIC_InitStructure);
 
       
        NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQChannel;  //选择中断通道5
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; //抢占式中断优先级设置为2
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;  //响应式中断优先级设置为2
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                                   //使能中断
        NVIC_Init(&NVIC_InitStructure);
}
 
因为有3个中断,因此依据前文所述,须要有3个bit来指定抢占优先级,所以选择第2组。又因为EXTI5-9共用一个中断响应函数,所以EXTI5选择的中断通道是EXTI9_5_IRQChannel,详细信息能够在头文件里查询得到。用到的NVIC相关的库函数在stm32f10x_nivc.c中,须要将此文件复制并加入到project中。详细位置能够查看关于GPIO的笔记。这段代码编译起来没有不论什么问题,可是在链接的时候就会报错,须要把STM32F10xR.LIB加入project中,详细位置在…KeilARMRV31LIBSTSTM32F10xR.LIB。
 
3.       IO口初始化
void IO_cfg()
{
       GPIO_InitTypeDef GPIO_InitStructure;
 
     
       GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;                                             //选择引脚2
       GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;           //输出频率最大50MHz
      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;                  //带上拉电阻输出
       GPIO_Init(GPIOE,&GPIO_InitStructure);
       GPIO_ResetBits(GPIOE,GPIO_Pin_2);                              //将PE.2引脚设置为低电平输出
 
     
       GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_5; //选择引脚2 3 5
       GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //选择输入模式为浮空输入
       GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;          //输出频率最大50MHz
       GPIO_Init(GPIOC,&GPIO_InitStructure);                                 //设置PC.2/PC.3/PC.5
     
     
       GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3 | GPIO_Pin_6;                  //选择引脚3 6
       GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;           //输出频率最大50MHz
      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;                  //带上拉电阻输出
       GPIO_Init(GPIOD,&GPIO_InitStructure);
     
     
       GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;                                         //选择引脚5
       GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;          //输出频率最大50MHz
      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;                  //带上拉电阻输出
       GPIO_Init(GPIOB,&GPIO_InitStructure);       
}
当中连接外部中断的引脚须要设置为输入状态,而连接LED的引脚须要设置为输出状态,初始化PE.2是为了使得按键的另外一端输出低电平。GPIO中的函数在stm32f10x_gpio.c中。
 
4.       把对应的IO口设置为中断线路
因为GPIO并非专用的中断引脚,因此在用GPIO来触发外部中断的时候须要设置将GPIO对应的引脚和中断线连接起来,详细代码例如以下:
void EXTI_cfg()
{
       EXTI_InitTypeDef EXTI_InitStructure;
       //清空中断标志
       EXTI_ClearITPendingBit(EXTI_Line2);
       EXTI_ClearITPendingBit(EXTI_Line3);
       EXTI_ClearITPendingBit(EXTI_Line5);
 
       //选择中断管脚PC.2 PC.3 PC.5
       GPIO_EXTILineConfig(GPIO_PortSourceGPIOC, GPIO_PinSource2);
       GPIO_EXTILineConfig(GPIO_PortSourceGPIOC, GPIO_PinSource3);
       GPIO_EXTILineConfig(GPIO_PortSourceGPIOC, GPIO_PinSource5);
 
       EXTI_InitStructure.EXTI_Line = EXTI_Line2 | EXTI_Line3 | EXTI_Line5; //选择中断线路2 3 5
       EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; //设置为中断请求,非事件请求
       EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling; //设置中断触发方式为上下降沿触发
       EXTI_InitStructure.EXTI_LineCmd = ENABLE;                                          //外部中断使能
      EXTI_Init(&EXTI_InitStructure);
}
EXTI_cfg中须要调用到的函数都在stm32f10x_exti.c。
 
5.       写中断响应函数
STM32不像C51单片机那样,能够用过interruptkeyword来定义中断响应函数,STM32的中断响应函数接口存在中断向量表中,是由启动代码给出的。默认的中断响应函数在stm32f10x_it.c中。因此我们须要把这个文件增加到project中来。
在这个文件里,我们发现,非常多函数都是仅仅有一个函数名,并没有函数体。我们找到EXTI2_IRQHandler()这个函数,这就是EXTI2中断响应的函数。我的目标是将LED灯点亮,所以函数体事实上非常easy:
void EXTI2_IRQHandler(void)
{
       //点亮LED灯
       GPIO_SetBits(GPIOD,GPIO_Pin_6);
       //清空中断标志位,防止持续进入中断
       EXTI_ClearITPendingBit(EXTI_Line2);
}
 
void EXTI3_IRQHandler(void)
{
       GPIO_SetBits(GPIOD,GPIO_Pin_3);
       EXTI_ClearITPendingBit(EXTI_Line3);
}
 
void EXTI9_5_IRQHandler(void)
{
       GPIO_SetBits(GPIOB,GPIO_Pin_5);
 
       EXTI_ClearITPendingBit(EXTI_Line5);
}
因为EXTI5-9是共用一个中断响应函数,因此全部的EXTI5 – EXTI9的响应函数都写在这个里面。
 
6.       写主函数
#include "stm32f10x_lib.h"
 
void RCC_cfg();
void IO_cfg();
void EXTI_cfg();
void NVIC_cfg();
 
int main()
{
          RCC_cfg();
          IO_cfg();
          NVIC_cfg();
          EXTI_cfg();
 
          while(1);

}

转自http://huhui1101.blog.163.com/blog/static/8784066520126294740460/

STM32外部中断具体解释相关推荐

  1. STM32外部中断与看门狗

    STM32外部中断与看门狗 前面说过中断的概念了,但是没有细究,中断除了内部中断(比如运行错误),还能受到外部中断 文章目录 STM32外部中断与看门狗 一 外部中断描述 1.1 外部中断描述 1.2 ...

  2. STM32外部中断与各通道对应关系

    EXTI0_IRQn的值,其实就是EXTI0中断向量在中断向量表中的位置(STM32技术参考手册中断向量表position栏中的数值) 一:外部中断使用配置过程: (1)配置时钟信号 (2)引脚属性 ...

  3. STM32外部中断干扰解决方案

    STM32 外部中断很容易受干扰误触发,无论上拉下拉设置都没有效果,最后采用软件判断解决该问题. 进入外部中断程序需同时判断引脚电平是否和上升触发和下降触发一致,这个判断很重要. void EXTI3 ...

  4. STM32外部中断总结

    STM32外部中断总结 STM32的外部中断是我们在学习stm32的一个必要模块,外部中断的用途可以增加人机交互的体验,也可以增加程序的执行效率.下面将以一个小实验来记录外部中断的使用需要注意的事项 ...

  5. STM32——外部中断

    目录 外部中断简述 什么是外部中断 传统单片机与新型单片机外部中断区别 STM32外部中断请求 STM32中断线与IO口的对应 STM32 中断服务函数 外部中断与中断服务函数的对应 中断服务函数列表 ...

  6. 采用STM32外部中断模式控制LED灯亮灭

    文章目录 实验工具 一.STMCube配置项目 1.配置引脚 2.配置EXIT 3.配置SYS 4.配置GPIO 5.创建代码 二.使用KEil配置代码 1.打开生成的项目,找到stm32f1xx_i ...

  7. 【嵌入式STM32-05】STM32 外部中断 EXTI 基本原理|库函数程序代码|寄存器

    STM32外部中断 1.中断基本原理 中断:在主程序运行过程中,出现了特定的中断触发条件(中断源),使得CPU暂停当前正在运行的程序,转而去处理中断程序,处理完成后又返回原来被暂停的位置继续运行 中断 ...

  8. STM32外部中断与(NVIC)中断优先级管理

    文章目录 1.中断介绍 1.中断的概念 2.中断的产生 3.中断处理的流程 2.STM32内嵌向量中断控制器NVIC 1.NVIC控制器的寄存器 2.STM32中断配置 3.STM32外部中断EXIT ...

  9. stm32 外部中断学习

    今天我们看看STM32的外部中断实验. STM32 供 IO 口使用的中断线只有 16 个,但是 STM32 的 IO 口却远远不止 16 个,那么 STM32 是怎么把 16 个中断线和 IO 口一 ...

  10. stm32外部中断_STM32学习笔记 | 电源管理及低功耗设计要点

    一款好的电子产品,都需要认真考虑电源管理的问题,电池供电的产品更应该注意低功耗的实现. STM32电源介绍 嵌入式开发直播课 - STM32 USART串口的应用 - 创客学院直播室​www.make ...

最新文章

  1. lamp配置python_LAMP自动化安装脚本
  2. 解决Fedora没有最大化最小化按钮
  3. 阿里资深技术专家崮德:如何成就更好的自己
  4. 数据结构 线性链表栈
  5. Pytest之pytest-assume同用例多断言,断言1失败会执行后续代码及断言2
  6. windows 安装mongodb
  7. (140)FPGA面试题-FPGA IP简介
  8. python实现发送免费短信功能
  9. hadoop搭建之hadoop安装
  10. 服务器重启之后自动登录并启动程序
  11. 百度人脸识别文档冲突,facetype应是face_type
  12. UCBCS188 AI学习笔记(1)uninformed search (无启发函数搜索)
  13. fiddler一直报错502
  14. windowsXP sp3 升级包
  15. 支持hicar的华为手机
  16. 一线大厂软件测试流程(思维导图)详解
  17. win10 插入鼠标自动禁用触摸板的方法
  18. 几张思维导图告诉你搜索引擎优化(SEO)核心点
  19. Android Application创建到Activity启动(launcher启动和startActivity启动)
  20. 测试ios软件开发,iOS开发中的测试框架

热门文章

  1. 怎么把jdk和jRE的Javadoc文档整合到MyEclipse
  2. ASP.NET中用healthMonitor属性用法
  3. 如何防止用户重复提交数据
  4. 循环控制-链表删除结点
  5. 【bzoj5166】[HAOI2014]遥感监测 贪心
  6. ubuntu 安装Pangolin 过程
  7. Leetcode 627. Swap Salary
  8. 支持语言locale
  9. sublime ctrl b突然不能用解决方法
  10. CSS3知识点总结---transitionend