您的位置 首页 芯闻

STM32外部中止详细解说

一、基本概念ARMCoetex-M3内核共支持256个中断,当中16个内部中断,240个外部中断和可编程的256级中断优先级的设置。STM32眼下支持的中…

一、根本概念

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);

}

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/news/xinwen/263908.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部