stm32 外部中断的使用(含实例)

发布者:cheng1984最新更新时间:2020-12-01 来源: eefocus关键字:stm32  外部中断  嵌入式系统 手机看文章 扫描二维码
随时随地手机看文章

中断对于开发嵌入式系统来讲的地位绝对是毋庸置疑的,在C51单片机时代,一共只有5个中断,其中2个外部中断,2个定时/计数器中断和一个串口中断,但是在STM32中,中断数量大大增加,而且中断的设置也更加复杂。今天就将来探讨一下关于STM32中的中断系统


1 基本概念

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)如果某个中断源被指定为某个抢占式优先级别,又没有其它中断源处于同一个抢占式优先级别,则可以为这个中断源指定任意有效的响应优先级别。


2 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。对于NVIC的详细解释,可以参考《ARM Cortex-M3权威指南》,Joseph Yiu著,宋岩译,北京航空航天大学出版社出版,第8章NVIC与中断控制。中断的使能,挂起,优先级,活动等等部都是NVIC在管理的。因为我学习STM32重点在于如何开发程序,所以内部的一些东西,在此我就不详细说明了,有感兴趣的可以参看上面提到的那本数。


3 程序开发

其实上面那些基本概念和知识只是对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 PB端口时钟,并且打开复用时钟

       RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE| RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOB |RCC_APB2Periph_AFIO, ENABLE);

}

    设置相应的时钟所需要的RCC函数在stm32f10x_rcc.c中,所以要在工程中添加此文件。

 

2. 设置好相应的中断

设置相应的中断实际上就是设置NVIC,在STM32的固件库中有一个结构体NVIC_InitTypeDef,里面有相应的标志位设置,然后再用NVIC_Init()函数进行初始化。详细代码如下:

void NVIC_cfg()

{

        NVIC_InitTypeDefNVIC_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中,需要将此文件复制并添加到工程中。具体位置可以查看关于GPIO的笔记。这段代码编译起来没有任何问题,但是在链接的时候就会报错,需要把STM32F10xR.LIB加入工程中,具体位置在…KeilARMRV31LIBSTSTM32F10xR.LIB。

 

3.IO口初始化

void IO_cfg()

{

       GPIO_InitTypeDefGPIO_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_InitTypeDefEXTI_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; //设置为中断请求,非事件请求

[1] [2]
关键字:stm32  外部中断  嵌入式系统 引用地址:stm32 外部中断的使用(含实例)

上一篇:经典_STM32_ADC多通道采样的例子
下一篇:STM32之can 实例+代码解析

推荐阅读最新更新时间:2024-11-02 19:13

STM32(9) GPIO口复用功能实现(正点原子)
一个GPIO口可以 复用成内部外设的功能引脚,这里我们利用PA9PA10设置为UART1来举例。 IO口对应的复用功能需要查表来确定。这个表在芯片手册 下面这个图讲解了GPIO口的复用原理 上图右边左图是复用器(AFRL(31:0)、AFRH(31:0)),要复用哪个引脚就将相应的GPIO连接到复用器上,即可。 那么接下来我们就讲解 一下如何利用复用器去将GPIO口配置成复用功能。AFRL和AFRH都是32的寄存器,每一个GPIO口占用4位,所以在一组IO口中,他的低8位(PA0-PA7)占用AFRL,他的高8位(PA8-PA15)占用AFRH。 例如:我们要配置GPIOA2配置成UART2, 1.G
[单片机]
<font color='red'>STM32</font>(9) GPIO口复用功能实现(正点原子)
嵌入式系统优先级反转问题的分析
  引言   VxWorks是美国Wind River(风河)公司的一个实时操作系统,具有良好的可靠性和实时性。该系统采用基于优先抢占式调度策略,系统为每一个任务分配一个优先级,调度程序保证当前运行的是优先权最高的任务。但在实际开发中,由于任务间资源共享,信号量及中断的引入,往往会出现高优先级任务被低优先级任务长时间阻塞或阻塞一段不确定时间的现象,即所谓优先级反转(Priority Inversion)。优先级反转会造成任务调度的不确定性,严重时可能导致系统崩溃。本文在参考文献的基础上,结合实际项目开发过程中遇到的优先级反转问题,对造成优先级反转的原因及其解决方法进行了探讨。   优先级反转一般性描述   优先级反转发生
[嵌入式]
基于嵌入式系统的手机编程开发平台
   引 言   随着移动通信技术的飞速发展,手机已经从单一的电话通信设备转变为信息网络终端,因此,近年来手机编程已经成为一项重要的技术。手机是一个高新技术的集合体,包含了移动终端、嵌入式系统、数字信号处理以及通信协议设置等多项技术。手机编程开发平台是集合了通信技术、嵌入式技术、电子技术、软件工程、操作系统等理论的软硬件的教学与研究开发平台。在这个开发平台上开发相应的程序,可以掌握嵌入式系统设计的流程与方法;可以根据使用者的需求,设计并实现手机的基本功能和扩展功能。    1 手机编程开发平台总体结构   作为专业技术课程,手机编程技术的教学内容包括系统设置、操作系统使用以及应用软件开发,因此,手机编程平台必须支持各项
[嵌入式]
STM32之FSMC
STM32 FSMC总线深入研究 由于CPU与FPGA通信的需要,以及对8080总线的熟悉,首选采用了STM32的FSMC总线,作为片间通信接口。FSMC能达到16MHz的写入速度,理论上能写20fps的1024*768的图片哈哈。(当然实际上是不可能的,就算是DMA传输,数据源也跟不上,实际上刷模拟的图片每秒10fps,刷的很high)当然这不是本篇的要点,这里主要研究STM32的FSMC接口,将速度提升到极限。 1. FSMC协议分析 如下为ILI9325的8080接口的协议 CS(片选信号):低电平片选有效,高电平失能(默认为高:失能) RS(数据寄存器):低电平写寄存器,高电平写数据(默认为高:写数据
[单片机]
<font color='red'>STM32</font>之FSMC
STM32 基础系列教程 2 - GPIO 按键输入
前言 学习stm32 GPIO 的使用,实现简单的按键输入功能,用按键的高低来控制LED的亮灭! 示例详解 基于硬件平台: STM32F10C8T6最小系统板, MCU 的型号是 STM32F103c8t6, 使用stm32cubemx 工具自动产生的配置工程,使用KEIL5编译代码。将PA0引脚设置成输入引脚,程序得到PA0引脚的(按键操作)输入状态,并根据其输入电平的高低来控制PC13输出,来控制LED,实现按一次LED亮,再按一下,LED灭的功能。 本示例所用的最小系统板原理图: 新建STM32 CUBEMX 工程, 双击桌面STM32CubeMX工具 在CubeMX中菜单中点 File à New
[单片机]
<font color='red'>STM32</font> 基础系列教程 2 - GPIO 按键输入
以C51单片机为核心的嵌入式系统实时控制设计
随着现代通信技术的发展,通信测试仪器不断推陈出新。各种新型设备对系统的实时响应能力的要求越来越高,一种通信测试仪器的实时响应性能,就成为系统设计能否成功的关键因素之一。笔者曾在多个通信测试仪器项目中,成功地应用ARM处理器、C51单片机等为主控芯片的嵌入式系统,实现了对仪器相关模块的实时控制功能。因此提出一种在某通信测试仪器中使用C51单片机来实现实时控制的设计方案。 1 硬件设计与实现 1.1 总体方案设计 在该通信测试仪器中,实时控制模块主要实现对射频接收频综、射频发生频综、滤波器组件、射频输入模块、射频输出模块等实时控制作用。对射频检波信号进行A/D转换以获取数据。与上位计算机进行通信等功能。 根据待实现的系统功能要
[单片机]
以C51单片机为核心的<font color='red'>嵌入式系统</font>实时控制设计
STM32启动过程全解
本文主要阐述了STM32启动过程全面解析,包括启动过程的介绍、启动代码的陈列以及深入解析。   相对于ARM上一代的主流ARM7/ARM9内核架构,新一代Cortex内核架构的启动方式有了比较大的变化。ARM7/ARM9内核的控制器在复位后,CPU会从存储空间的绝对地址0x000000取出第一条指令执行复位中断服务程序的方式启动,即固定了复位后的起始地址为0x000000(PC = 0x000000)同时中断向量表的位置并不是固定的。而Cortex-M3内核则正好相反,有3种情况:   1、 通过boot引脚设置可以将中断向量表定位于SRAM区,即起始地址为0x2000000,同时复位后PC指针位于0x2000000处;  
[模拟电子]
<font color='red'>STM32</font>启动过程全解
stm32异步串口通讯配置过程
| 串口是一种全双工通讯方式 单工 数据传输只支持数据在一个方向上传输 半双工 允许数据在两个方向上传输,在同一时刻,只允许数据在一个方向上传输,它实际上是一种切换方向的单工通信 全双工 允许数据同时在两个方向上传输,因此,全双工通信是两个单工通信方式的结合,它要求发送设备和接收设备都有独立的接收和发送能力 异步串口常见连接方式 相同端口数据传输 不同端口数据传输 这里必须保证通讯两端数据共地,此外还需注意不同端口间的电平转换,如TTL、232. | 异步通讯时序图 这里以8位字长为例,进行数据传输时,接收方首先捕捉数据起始位- -由高电平到低电平的数据跳变,低电平会保持一个数据周期(空闲时,数据线保持高电平)
[单片机]
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
  • 学习ARM开发(16)
    ARM有很多东西要学习,那么中断,就肯定是需要学习的东西。自从CPU引入中断以来,才真正地进入多任务系统工作,并且大大提高了工作效率。采 ...
  • 学习ARM开发(17)
    因为嵌入式系统里全部要使用中断的,那么我的S3C44B0怎么样中断流程呢?那我就需要了解整个流程了。要深入了解,最好的方法,就是去写程序 ...
  • 学习ARM开发(18)
    上一次已经了解ARM的中断处理过程,并且可以设置中断函数,那么它这样就可以工作了吗?答案是否定的。因为S3C44B0还有好几个寄存器是控制中 ...
  • 嵌入式系统调试仿真工具
    嵌入式硬件系统设计出来后就要进行调试,不管是硬件调试还是软件调试或者程序固化,都需要用到调试仿真工具。 随着处理器新品种、新 ...
  • 最近困扰在心中的一个小疑问终于解惑了~~
    最近在驱动方面一直在概念上不能很好的理解 有时候结合别人写的一点usb的例子能有点感觉,但是因为arm体系里面没有像单片机那样直接讲解引脚 ...
  • 学习ARM开发(1)
  • 学习ARM开发(2)
  • 学习ARM开发(4)
  • 学习ARM开发(6)
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved