微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > STM32外部中断具体解释

STM32外部中断具体解释

时间:11-20 来源:互联网 点击:
一、基本概念

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; //带

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top