关于STM32中NVIC的理解,带错误例子

发布者:cannon928最新更新时间:2016-07-11 来源: eefocus关键字:STM32  NVIC  错误例子 手机看文章 扫描二维码
随时随地手机看文章
STM32有43个channel的settable的中断源;AIRC(Application Interruptand Reset Register)寄存器中有用于指定优先级的4 bits。这4个bits用于分配preemption优先级和sub优先级,在STM32的固件库中定义如下

/* Preemption Priority Group-------------------------------------------------*/
#define NVIC_PriorityGroup_0         ((u32)0x700) /* 0 bits for pre-emption priority
                                                     4 bits for subpriority */
#defineNVIC_PriorityGroup_1         ((u32)0x600) /* 1 bits for pre-emption priority
                                                     3 bits for subpriority */
#defineNVIC_PriorityGroup_2         ((u32)0x500) /* 2 bits for pre-emption priority
                                                     2 bits for subpriority */
#define NVIC_PriorityGroup_3         ((u32)0x400) /* 3 bits for pre-emption priority
                                                     1 bits for subpriority */
#defineNVIC_PriorityGroup_4         ((u32)0x300) /* 4 bits for pre-emption priority
                                                     0 bits for subpriority */

 

NVIC_PriorityGroup

先占优先级取值范围

(PreemptionPriority取值)

次占优先级取值范围

(SubPriority取值)

NVIC_PriorityGroup_0

0(只看SubPriority取值)

0到15

NVIC_PriorityGroup_1

0到1

0到7

NVIC_PriorityGroup_2

0到3

0到3

NVIC_PriorityGroup_3

0到7

0到1

NVIC_PriorityGroup_4

0到15

0(只看PreemptionPriority取值)

 

说明一下:

1、所设定的值中,值越小,中断优先级越高。

 

2、如果选用NVIC_PriorityGroup_0,则函数中NVIC_IRQChannelPreemptionPriority中设置的值对中断通道优先级不产生任何影响。如果选用NVIC_PriorityGroup_4,则函数中NVIC_IRQChannelSubPriority中设置的值对中断通道优先级不产生任何影响。

如下所示:

 

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0); //选用组0

 

       NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;

       NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;//这里这样设置无效       NVIC_InitStructure.NVIC_IRQChannelSubPriority= 0;

       NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;     

       NVIC_Init(&NVIC_InitStructure);

      

      

       NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;

       NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;

       NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;

       NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

       NVIC_Init(&NVIC_InitStructure);

如上所示,设置TIM3_IRQn的NVIC_IRQChannelPreemptionPriority为2是错误的,因为从表中可以看到,选组0时NVIC_IRQChannelPreemptionPriority的值只能为0。

同理,如果选用NVIC_PriorityGroup_4,那么NVIC_IRQChannelSubPriority的值只能为0。

3、一般配置NVIC代码如下

voidNVIC_Configuration(void){

      

       NVIC_InitTypeDef NVIC_InitStructure;

       /* 初始化向量表取值 */

       #ifdef VECT_TAB_RAM 

       /* Set the Vector Table base location at 0x20000000 */

       NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0);

       #else /* VECT_TAB_FLASH */ 

       /* Set the Vector Table base location at 0x08000000 */

       NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0); 

       #endif

 

       /* 选择所使用的要使用的组别*/

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4); //这句代码在整个程序中只能写一次

 

       //设定定时器中断先占优先级为2,低于串口中断优先级

       NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;

       NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;

       NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;

       NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;     

       NVIC_Init(&NVIC_InitStructure);

 

       //设定串口中断先占优先级为0,为最高优先级

       NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;

       NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;

       NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;

       NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

       NVIC_Init(&NVIC_InitStructure);

      

}             

 

下面是网上找的一些理解,也挺不错的!

 

形象化的理解是:


你是上帝,
造了43个人,这么多人要分社会阶级和社会阶层了;
因为“阶级”的词性比较重;"阶层"比较中性,
所以preemption优先级->阶级;每个阶级内部,有一些阶层,sub优先级->阶层;


如果按照NVIC_PriorityGroup_4这么分,就分为了16个阶级(1个阶层就是1个preemption优先级),0个阶层;高阶级的人,可以打断低阶级的正在做事的人(嵌套),最多可以完成1个中断和15级嵌套。
每个阶级(每个preemption优先级),你来指定这43人中,谁进入该阶级;一个人叫EXTI0_IRQChannel,你指定他进入“阶级8”,则
NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQChannel;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 8; // 指定抢占式优先级别1,可取0-15


另外,在同一阶级内部,一个人在做事的时候,另外一个人不能打断他;(preemption优先级别相同的中断源之间没有嵌套关系)
还有,如果他们两个同时想做事,因为没有阶层,那么就根据Vector table中的物理排序,让排名靠前的人去做;


又有1个人SPI1_IRQChannel,设定如下
NVIC_InitStructure.NVIC_IRQChannel = SPI1_IRQChannel;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; // 指定抢占式优先级别1,可取0-15


SPI1_IRQChannel的阶级高,EXTI0_IRQChannel做事的时候可以打断(嵌套)。


如果按照NVIC_PriorityGroup_3这么分,就分为了8个阶级(1个阶级是1个preemption优先级),每个阶级内有2个阶层(sub优先级);高阶级的人,可以打断低阶级的正在做事的人(嵌套),最多可以完成1个中断和7级嵌套。

每个阶级(每个preemption优先级),你来指定这43人中,谁进入该阶级;一个人叫EXTI0_IRQChannel,你指定他进入“阶级3”,则:
NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQChannel;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3; // 指定抢占式优先级别1,可取0-7
还需要指定他的阶层:
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; // 指定响应优先级别0,可取0-1


另有1个人叫EXTI9_5_IRQChannel,他的阶级和阶层设定如下
NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQChannel;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3; // 指定抢占式优先级别0,可取0-7
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; // 指定响应优先级别1


那么这两个人是同一阶级的兄弟,一个人在做事的时候,另外一个人不能打断他;(preemption优先级别相同的中断源之间没有嵌套关系)
如果他们两个同时想做事,因为前者的阶层高,所以前者优先。


还有一个人叫USART1_IRQChannel,他的阶级和阶层设定如下
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQChannel;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; // 指定抢占式优先级别0,可取0-7
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; // 指定响应优先级别1


USART1_IRQChannel的优先级最高,当前面两个人做事的时候,他都可以打断(嵌套)。


以下的类推。

 
关键字:STM32  NVIC  错误例子 引用地址:关于STM32中NVIC的理解,带错误例子

上一篇:s3c6410硬件RTC实时时钟
下一篇:stm32 nvic的理解

推荐阅读最新更新时间:2024-03-16 14:59

关于STM32系列微控制器的几点认识
STM32系列微控制器是意法半导体旗下的产品,凭借着自身的高性能,低功耗,丰富的数字外围设备和强大的电气处理能力等优势,广泛地应用在工业控制及自动化,消费类电子产品,智能硬件等领域。很多院校和嵌入式培训机构都选用此系列微控制器作为典型的教材! 此系列微控制器采用ARM CORTEX-M处理器内核,关于ARM架构的优势,毋庸置疑是最优秀的架构之一,其CORTEX-A系列微处理器几乎垄断整个移动设备领域!在ARM内核基础上,ST加上自己的数字外围设备,使其具备处理复杂电气问题的能力,例如通过定时器的PWM功能控制电机,通过普通输出端口控制外部继电器,通过片上AD获得外部模拟信号等等,以此系列微控制器为主控的产品不计其数,例如伺服电机
[单片机]
关于<font color='red'>STM32</font>系列微控制器的几点认识
STM32学习笔记—引起电源和系统异常复位的原因
每一块处理器都有复位的功能,不同处理器复位的类型可能有差异,引起复位的原因也可能有多种。 STM32的复位功能非常强大,可通过软件、硬件和一些事件触发系统复位,而且通过其复位状态标志可分析复位原因。该部分位于STM32的RCC(Reset and Clock Control)模块。 STM32 复位介绍 对于STM32来说,复位通常分为三种类型:系统复位、电源复位和备份域复位。本文结合STM32F4描述系统和电源复位的内容。 1. 系统复位 除了RCC的复位标志和备份域中的寄存器外,系统复位会将其它全部寄存器都复位为复位值。 产生系统复位事件: NRST 引脚低电平 窗口看门狗计数结束 独立看门狗计数结束 软件
[单片机]
基于Cortex-M3的STM32微控制器处理先进电机控制方法
变频器的问世和先进的电机控制方法让三相无刷电机(交流感应电机或永磁同步电机)曾经在调速应用领域取得巨大成功。这些高性能的电机驱动器过去主要用于工厂自动化系统和机器人。十年来,电子元器件的大幅降价使得这些电机驱动器能够进入对成本敏感的市场,例如:家电、空调或个人医疗设备。本文将探讨基于ARM的标准微控制器如何在一个被DSP和FPGA长期垄断的市场上打破复杂的控制模式,我们将以意法半导体的基于Cortex-M3 内核的STM32系列微控制器为例论述这个过程。 图 3 : STM32: 强固的增长基础 首先,我们回顾一下电机控制的基本原理。在电机控制系统内,为什么处理器非常重要?我们为什么需要非常好的计算性能?毕竟,
[单片机]
基于Cortex-M3的<font color='red'>STM32</font>微控制器处理先进电机控制方法
通过 stm32 cubemx 配置 串口中断
首先选择好串口 ① 第三项的配置 ② 第三项 ③串口的全局中断 ④部分代码: voidHAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { if(HAL_UART_Receive_IT(&huart1,a1,1)!=HAL_OK) //判断是否接受到电脑传输过来的数据,并放入到数组a1。 { Error_Handler(); }else { HAL_GPIO_EXTI_Callback(GPIO_PIN_6); } } voidHAL_G
[单片机]
通过 <font color='red'>stm32</font> cubemx 配置 串口中断
一种导致STM32重新上电后不工作的原因
【使用环境】 编译器:KEIL5.20 硬件:STM32F429 软件:FreeRTOS 【问题描述】 编译后烧录运行正常,重新上电无反应 【问题分析】 1. 在任务中使用了非系统延时 --非系统延时导致系统阻塞, 详看 2. 外设驱动初始化问题 --有些外设在重新上电后初始化失败,导致错误或是卡在此处 如MPU6050就需要在初始化前加入一定延时,不然再次初始化会失败 如GT811触摸芯片复位准备时长需要50ms 3. 配置为外部中断的GPIO悬空导致 --由于该引脚为悬空状态,且该引脚配置为中断模式,在上电时无法确定该引脚的电平状态,导致初始化瞬间产生一个边沿跳变,而进入中断,此时系统还未初始化完毕,导致中断服务程
[单片机]
知道STM32串口通信乱码要怎么处理吗
STM32串口通信以及温度采集搞定,其中主要遇到STM32系列单片机时钟树的问题,串口通信遇到串口调试助手能够接收到数据但出现乱码现象。 开始一直以为是串口配置和程序代码问题,因为是第一次上电在线调试STM32板子,后面主要查串口波特率配置和收发函数程序段,如下图: 波特率设置成115200没问题,试着降低波特率改成9600和4800但问题依旧没有解决,紧接着如下处理: 将重定向函数注释,单独写串口发送字节和字符串函数,依旧失败。最后锁定到系统时钟配置上,由于手上的STM32开发板改用了12M的晶振,根据单片机时钟树的理解和解读,一般采用外部时钟HSE,系统时钟配置成72M,8*9=72,,12*6=72,对于 SYS
[单片机]
知道<font color='red'>STM32</font>串口通信乱码要怎么处理吗
STM32中断与事件
关于事件、中断事件 、中断三个概念的比喻 比如一老师在教室里给学生们上课。课堂上的学生可能做出各种行为动作,比方做笔记、打哈气、翻书包、讲小话等,我们把这些行为统称为事件,其中有些行为老师往往只是视而不见,继续他的上课;而有些行为可能导致老师的上课中止,比方讲小话,并对学生的相关行为予以警告、批评或纠正等,然后继续上课。我们把老师因为学生的某些行为而中止授课,并产生后续动作,之后接着上课的这个过程理解为中断或中断响应。我们把可能导致老师上课中断的学生行为理解为中断事件。 结合具体的ST MCU运行过程 ST MCU运行过程,其中会有许多各种各样的事件,比方管脚电平变化、计数器溢出、DMA空、FIFO非空、AD转换结束、超时、
[单片机]
stm32专题二十六:互补输出 死区刹车
互补输出+死区刹车 这一部分代码,主要是初始化3个结构体,包括时基结构体、输出比较结构体和死区配置结构体,要对照前一篇博客和中文参考手册中的寄存器说明来仔细看,代码如下: bsp_AdvanceTim.c #include bsp_AdvanceTim.h static void ADVANCE_TIM_GPIO_Config(void) { GPIO_InitTypeDef GPIO_InitStructure; // 输出比较通道 GPIO 初始化 RCC_APB2PeriphClockCmd(ADVANCE_TIM_CH1_GPIO_CLK, ENABLE); GPIO_InitStructure.G
[单片机]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

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

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