【转-Andrew_qian】stm32中断嵌套全攻略
断断续续学习STM32一学期了,时间过的好快,现在对STM32F103系列单片机的中断嵌套及外部中断做一个总结,全当学习笔记。废话不多说,ARM公司的Cortex-m3 内核,支持256个中断,其中包含16个内核中断和240个外部中断,并且具有256级的可编程中断设置。在ST公司的STM32单片机中最多有84个中断,包括16个内核中断(这16个内部中断是任何半导体商也改不了的),和68个可屏蔽中断,具有16级可编程的中断优先级。但是在STM32F103系列中只有60个可屏蔽中断,(107系列有68个)。
针对这60个可屏蔽中断,重点掌握它的一个中断优先级寄存器组IPR,全称Interrupt Priority Registers。这个寄存器组包含15个32位的寄存器,一个可屏蔽中断占用8bit,那么一个寄存器可以控制4个可屏蔽中断,一共15*4=60。然而在这占用的8bit中又只使用了高4bit,这高4bit的分配才是STM32F103系列单片机中断嵌套的设置所在。STM32F103系列的中断嵌套分为5个组,分别是0、1、2、3、4 这5个组,下面是5个组与中断嵌套的对应关系。
组
|
分配结果
|
0
|
0位抢占优先级,4位响应优先级
|
1
|
1位抢占优先级,3位响应优先级
|
2
|
2位抢占优先级,2位响应优先级
|
3
|
3位抢占优先级,1位响应优先级
|
4
|
4位抢占优先级,0位响应优先级
|
对于抢占优先级和响应优先级,只需记住两点,第一、抢占任何优先级比都比所有响应优先级优先级高。只有抢占优先级更高的具有中断嵌套功能。(即打断其他正在执行的中断)。第二、数字越小优先级越高 ,抢占优先级和响应优先级都一样时,首先响应中断通道对应中断向量地址低的那个中断。
下面对0组和1组的情况做一个分析。
0组对应是0位抢占优先级,4位响应优先级,那么无抢占优先级,响应优先级可设置为0到15级(2的4次方种)中的任意一种。
1组对应是1位抢占优先级,3位响应优先级,那么抢占优先级只可设置为0级或者1级中的任意一种(2的1次方种),响应优先级可设置为0到7级(2的3次方种)中的任意一种。
上电复位时,中断配置为4组,并且60个外部中断都是抢占优先级为0级,无响应优先级。
总结一下:
- 高优先级的抢占优先级是可以打断正在进行的低抢占优先级中断的。
- 抢占优先级相同的中断,高响应优先级不可以打断低响应优先级的中断。
- 抢占优先级相同的中断,当两个中断同时发生的情况下,哪个响应优先级高,哪个先执行。
- 如果两个中断的抢占优先级和响应优先级都是一样的话,则看哪个中断先发生就先执行。
所以可以看出判断两个中断的优先级时先看抢占优先级的高低,如果相同再看响应优先级的高低。如果全都相同最后看中断通道向量地址。
一般来说在使用过程中,一个系统使用一个组别就完全可以满足需要。所以在使用一个组别后一般不要在系统中再改动组别,骨灰级玩家可以去试试(小心芯片烧了)。
外部中断:
STM32F103的外部中断EXTI支持19个外部中断/事件请求。每个中断/事件都有独立的触发和屏蔽设置。
0到15线:对应外部I/O口输入中断
线16:接到PVD输出
线17:接到RCT闹钟事件
线18:接到USB唤醒事件
线16到线18我自己都没用过,主要对线0到15的I/O输入中断做一个总结,有个注意的地方是这0到15线的外部中断,其中0到4线,这5个外部中断都有自己单独的中断响应函数。5到9线公用一个中断服务函数,10到15线公用一个中断服务函数。
外部中断配置寄存器组EXTICR包含4个32位的寄存器,分别是EXTICR0、EXTICR1、EXTICR2、EXTICR3、但每一个寄存器只用了低16位,每4位控制一个I/O口,一个寄存器控制4个I/O口,EXTICR寄存器组控制16个I/O口,刚好一个GPIO的I/O口数。下面以 EXTICR0为例,用一个表格表示:
I/O口3
|
I/O口2
|
I/O口1
|
I/O口0
|
0000 GPIOA
|
0000 GPIOA
|
0000 GPIOA
|
0000 GPIOA
|
0001 GPIOB
|
0001 GPIOB
|
0001 GPIOB
|
0001 GPIOB
|
0010 GPIOC
|
0010 GPIOC
|
0010 GPIOC
|
0010 GPIOC
|
0011 GPIOD
|
0011 GPIOD
|
0011 GPIOD
|
0011 GPIOD
|
0100 GPIOE
|
0100 GPIOE
|
0100 GPIOE
|
0100 GPIOE
|
0101 GPIOF
|
0101 GPIOF
|
0101 GPIOF
|
0101 GPIOF
|
0110 GPIOG
|
0110 GPIOG
|
0110 GPIOG
|
0110 GPIOG
|
比如配置GPIOA.0就是将EXTICR0的低4位配置成0000,若配置GPIOB.1就是配置EXTICR0的4到7位,为0001。
这里有一个问题,如果要配置GPIOA.0和GPIOB.0,会引起冲突,不知道是不是分时配置解决的。我用的固体库的方式,不需要考虑这些,呵呵。注意使用固件库时中断复位函数是写在stm32f10x_it.c这个文件里的。
下面结合外部中断附上固件库版本的程序:
主函数里:

void NVIC_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitSructure; NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置为优先级组2 NVIC_InitSructure.NVIC_IRQChannel = EXTI15_10_IRQn; //定义外部中断线13中断通道
NVIC_InitSructure.NVIC_IRQChannelPreemptionPriority = 0; //抢占优先级0
NVIC_InitSructure.NVIC_IRQChannelSubPriority = 0; //响应优先级0
NVIC_InitSructure.NVIC_IRQChannelCmd = ENABLE; //使能指定通道
NVIC_Init(&NVIC_InitSructure); NVIC_InitSructure.NVIC_IRQChannel = EXTI15_10_IRQn; //定义外部中断线15中断通道
NVIC_InitSructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitSructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitSructure.NVIC_IRQChannelCmd = ENABLE; //使能指定通道
NVIC_Init(&NVIC_InitSructure); NVIC_InitSructure.NVIC_IRQChannel = EXTI0_IRQn; //定义外部中断线0中断通道
NVIC_InitSructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitSructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitSructure.NVIC_IRQChannelCmd = ENABLE; //使能指定通道
NVIC_Init(&NVIC_InitSructure); } void EXTI_Configuration(void)
{
EXTI_InitTypeDef EXTI_InitStructure; //初始化结构 GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource13); //指明当前哪个引脚为外部中断触发引脚
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource15); EXTI_ClearITPendingBit(EXTI_Line13); //清除中断标志位 EXTI_Line13对应相应的中断线13
EXTI_ClearITPendingBit(EXTI_Line15); EXTI_InitStructure.EXTI_Mode =EXTI_Mode_Interrupt; //选择中断模式请求
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; //下降沿触发
EXTI_InitStructure.EXTI_Line = EXTI_Line13|EXTI_Line15; // 选择待使能的外部中断线
EXTI_InitStructure.EXTI_LineCmd = ENABLE; // 定义选中线的新状态 使能
EXTI_Init(&EXTI_InitStructure); //把EXIT_InitStructure中的每一个参数按缺省值填入 GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource0); //指明当前哪个引脚为外部中断触发引脚
EXTI_ClearITPendingBit(EXTI_Line0);
EXTI_InitStructure.EXTI_Mode =EXTI_Mode_Interrupt; //选择中断模式请求
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising; //上升沿触发
EXTI_InitStructure.EXTI_Line = EXTI_Line0; // 选择待使能的外部中断线
EXTI_InitStructure.EXTI_LineCmd = ENABLE; // 定义选中线的新状态 使能
EXTI_Init(&EXTI_InitStructure); //把EXIT_InitStructure中的每一个参数按缺省值填入 } stm32f10x_it.c这个文件里
void EXTI15_10_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_Line13)!=RESET)
{ GPIO_WriteBit( GPIOA,GPIO_Pin_8,(BitAction)(1-GPIO_ReadOutputDataBit(GPIOA,GPIO_Pin_8))); //LED0翻转
EXTI_ClearITPendingBit(EXTI_Line13);
}
if(EXTI_GetITStatus(EXTI_Line15)!=RESET)
{ GPIO_WriteBit( GPIOD,GPIO_Pin_2,(BitAction)(1-GPIO_ReadOutputDataBit(GPIOD,GPIO_Pin_2))); //LED0翻转
EXTI_ClearITPendingBit(EXTI_Line15); } } void EXTI0_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_Line0)!=RESET)
{ GPIO_WriteBit( GPIOA,GPIO_Pin_8,(BitAction)(1-GPIO_ReadOutputDataBit(GPIOA,GPIO_Pin_8))); //LED0翻转
GPIO_WriteBit( GPIOD,GPIO_Pin_2,(BitAction)(1-GPIO_ReadOutputDataBit(GPIOD,GPIO_Pin_2))); //LED0翻转 EXTI_ClearITPendingBit(EXTI_Line0);
}
}

【转-Andrew_qian】stm32中断嵌套全攻略的更多相关文章
- 【转】stm32中断嵌套全攻略
断断续续学习STM32一学期了,时间过的好快,现在对STM32F103系列单片机的中断嵌套及外部中断做一个总结,全当学习笔记.废话不多说,ARM公司的Cortex-m3 内核,支持256个中断,其中包 ...
- Moon.Orm3.8技术全攻略
Moon.ORM技术全攻略 一.绪论 本文主要是针对Moon.ORM的技术的讨论及其使用使用指导.如有其它疑问,请留言.本文主要针对Moon.ORM3.9版本,同时将会对4.0做一个技术预览.本文从 ...
- 用C#制作PDF文件全攻略
用C#制作PDF文件全攻略 目 录 前 言... 3 第一部分 iText的简单应用... 4 第一章 创建一个Document 4 第一步 创建一个Document实例:... 5 第二步 ...
- 【转】轻松搞定FTP之FlashFxp全攻略
转载网址:http://www.newhua.com/2008/0603/39163.shtml 轻松搞定FTP之FlashFxp全攻略 导读: FlashFXP是一款功能强大的FXP/FTP软件,融 ...
- VS2013全攻略(安装,技巧,快捷键,插件)!
工欲善其事,必先利其器.VS2013全攻略(安装,技巧,快捷键,插件)! 之前一篇<c++的性能, c#的产能?!鱼和熊掌可以兼得,.NET NATIVE初窥>承蒙大家喜爱和编辑推荐,在此 ...
- Windows Socket五种I/O模型——代码全攻略(转)
Winsock 的I/O操作: 1. 两种I/O模式 阻塞模式:执行I/O操作完成前会一直进行等待,不会将控制权交给程序.套接字 默认为阻塞模式.可以通过多线程技术进行处理. 非阻塞模式:执行I/O操 ...
- Anaconda使用教程全攻略
Anaconda使用教程全攻略 本文转自 https://zhuanlan.zhihu.com/p/32925500 〇.序 Python是一种面向对象的解释型计算机程序设计语言, ...
- Android屏幕适配全攻略(最权威的官方适配指导)屏幕尺寸 屏幕分辨率 屏幕像素密度 dpdipdpisppx mdpihdpixdpixxdpi
Android屏幕适配全攻略(最权威的官方适配指导)原创赵凯强 发布于2015-05-19 11:34:17 阅读数 153734 收藏展开 转载请注明出处:http://blog.csdn.net/ ...
- 【C#代码实战】群蚁算法理论与实践全攻略——旅行商等路径优化问题的新方法
若干年前读研的时候,学院有一个教授,专门做群蚁算法的,很厉害,偶尔了解了一点点.感觉也是生物智能的一个体现,和遗传算法.神经网络有异曲同工之妙.只不过当时没有实际需求学习,所以没去研究.最近有一个这样 ...
随机推荐
- BUUCTF-[CISCN2019 华东南赛区]Web4
BUUCTF-[CISCN2019 华东南赛区]Web4 看题 点击Read somethings,会跳转到 http://3fd8b1f9-614f-47ff-8e79-0f678e7bb4eb.n ...
- 从零开始实现简单 RPC 框架 7:网络通信之自定义协议(粘包拆包、编解码)
当 RPC 框架使用 Netty 通信时,实际上是将数据转化成 ByteBuf 的方式进行传输. 那如何转化呢?可不可以把 请求参数 或者 响应结果 直接无脑序列化成 byte 数组发出去? 答:直接 ...
- netty系列之:搭建HTTP上传文件服务器
目录 简介 GET方法上传数据 POST方法上传数据 POST方法上传文件 总结 简介 上一篇的文章中,我们讲到了如何从HTTP服务器中下载文件,和搭建下载文件服务器应该注意的问题,使用的GET方法. ...
- 哲学家就餐问题-Java语言实现死锁避免
哲学家就餐问题-Java语言实现死锁避免 我死锁预防是至少破坏死锁产生的四个必要条件之一,带来的问题就是系统资源利用率低且不符合开发习惯,而死锁避免不是事先釆取某种限制措施破坏死锁的必要条件,只是注意 ...
- Python PIL、Pillow笔记
原文链接:https://blog.csdn.net/FlashKoala/article/details/90649464 一.PIL.Pillow简介 PIL(Python Imaging Lib ...
- [第十三篇]——Docker Compose之Spring Cloud直播商城 b2b2c电子商务技术总结
Docker Compose Compose 简介 Compose 是用于定义和运行多容器 Docker 应用程序的工具.通过 Compose,您可以使用 YML 文件来配置应用程序需要的所有服务.然 ...
- 什么是 baseline 和 benchmark
baseline 一个算法被称为 baseline 算法说明这个比目前这个算法还差的已经不能接受了,方法有革命性的创新点可以挖掘,且存在巨大提升空间和超越benchmark的潜力,只是由于发展初期导致 ...
- 一个简单的session传值学习
a.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UT ...
- CentOS7下编译安装redis-5.0.9
CentOS7下编译安装redis-5.0.9 本文地址http://yangjianyong.cn/?p=171转载无需经过作者本人授权 下载redis #code start wget https ...
- PHP中类的自动加载
在之前,我们已经学习过Composer自动加载的原理,其实就是利用了PHP中的类自动加载的特性.在文末有该系列文章的链接. PHP中类的自动加载主要依靠的是__autoload()和spl_autol ...