【STM32】进阶(一):抢占式优先级和响应式优先级(NVIC_PriorityGroupConfig)

这篇具有很好参考价值的文章主要介绍了【STM32】进阶(一):抢占式优先级和响应式优先级(NVIC_PriorityGroupConfig)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

【STM32】STM32单片机总目录

1、简介

STM32(Cortex-M3)中每个中断源都有两级优先级:抢占式优先级(pre-emption priority)和子优先级(subpriority),子优先级也叫响应式优先级。

1.1 抢占式优先级

望文知义,就是优先级高的可以抢占优先级的中断。

具有高抢占式优先级的中断可以在具有低抢占式优先级的中断处理过程中被响应,即中断嵌套,或者说高抢占式优先级的中断可以嵌套在低抢占式优先级的中断中。

1.2 子优先级(响应式优先级)

望文知义,就是当两个抢占式优先级同时来时,先处理响应式优先级高的(谁优先级高先响应谁)。

当两个中断源的抢占式优先级相同时,这两个中断将没有嵌套关系,当一个中断到来后,如果正在处理另一个中断,这个后到来的中断就要等到前一个中断处理完之后才能被处理。如果这两个中断同时到达,则中断控制器根据他们的响应优先级高低来决定先处理哪一个;如果他们的抢占式优先级和响应优先级都相等,则根据他们在中断表中的排位顺序决定先处理哪一个。

总结下便是:抢占式优先级>响应优先级>中断表中的排位顺序(其中“>”理解为比较的方向)。

2、划分优先级

每个中断源都需要被指定这两种优先级,如果用一个字节(8位)表示中断源,将这8位划分成两部分,用前几位表示抢占式优先级,后几位表示响应式优先级,可以有有8种分配方式,如下:

1. 所有8位用于指定响应优先级
2. 最高1位用于指定抢占式优先级,最低7位用于指定响应优先级
3. 最高2位用于指定抢占式优先级,最低6位用于指定响应优先级
4. 最高3位用于指定抢占式优先级,最低5位用于指定响应优先级
5. 最高4位用于指定抢占式优先级,最低4位用于指定响应优先级
6. 最高5位用于指定抢占式优先级,最低3位用于指定响应优先级
7. 最高6位用于指定抢占式优先级,最低2位用于指定响应优先级
8. 最高7位用于指定抢占式优先级,最低1位用于指定响应优先级

以上便是优先级分组的概念,但是Cortex-M3允许具有较少中断源时使用较少的寄存器位指定中断源的优先级,因此STM32把指定中断优先级的寄存器位减少到4位,这4个寄存器位的分组方式如下:

第0组:所有4位用于指定响应优先级
第1组:最高1位用于指定抢占式优先级,最低3位用于指定响应优先级
第2组:最高2位用于指定抢占式优先级,最低2位用于指定响应优先级
第3组:最高3位用于指定抢占式优先级,最低1位用于指定响应优先级
第4组:所有4位用于指定抢占式优先级

3、设置优先级分组模式

在程序初始化阶段,使用固件库函数NVIC_PriorityGroupConfig先来对优先级分组模式。
NVIC_PriorityGroupConfig(u32 NVIC_PriorityGroup)函数的参数共有5种:

NVIC_PriorityGroup_0 => 选择第0组
NVIC_PriorityGroup_1 => 选择第1组
NVIC_PriorityGroup_2 => 选择第2组
NVIC_PriorityGroup_3 => 选择第3组
NVIC_PriorityGroup_4 => 选择第4组

源码定义,在STM32F10x_FWLib\inc\misc.h中

#define NVIC_PriorityGroup_0         ((uint32_t)0x700) /*!< 0 bits for pre-emption priority
                                                            4 bits for subpriority */
#define NVIC_PriorityGroup_1         ((uint32_t)0x600) /*!< 1 bits for pre-emption priority
                                                            3 bits for subpriority */
#define NVIC_PriorityGroup_2         ((uint32_t)0x500) /*!< 2 bits for pre-emption priority
                                                            2 bits for subpriority */
#define NVIC_PriorityGroup_3         ((uint32_t)0x400) /*!< 3 bits for pre-emption priority
                                                            1 bits for subpriority */
#define NVIC_PriorityGroup_4         ((uint32_t)0x300) /*!< 4 bits for pre-emption priority
                                                            0 bits for subpriority */

NVIC_PriorityGroupConfig在源码STM32F10x_FWLib\src\misc.c中
主要设置这个寄存器SCB->AIRCR:SCB(系统控制块的内存映射结构)中的 AIRCR(应用程序中断/重置控制寄存器)

void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup)
{
  /* Check the parameters */
  assert_param(IS_NVIC_PRIORITY_GROUP(NVIC_PriorityGroup));
  
  /* Set the PRIGROUP[10:8] bits according to NVIC_PriorityGroup value */
  SCB->AIRCR = AIRCR_VECTKEY_MASK | NVIC_PriorityGroup;
}

这其实也很好理解,比如选择NVIC_PriorityGroup_1,那么抢占式优先级便占一位,也就是说可以有2个级别,可以设置为0和1,而响应优先级则占3位,也就是说可以有2^3个选择,可以设置为0~7;总共来说就可以区别16种优先级,多余16种优先级时,再按照中断表中的排位顺序执行。

举个例子吧,假如现在有4个外部中断,还有一个EXTI9_5中断,那么如果选择优先级分组为第1组,那么抢占式优先级便只有两种,5个中断就至少有3个在抢占式优先级上是相同的优先级上,其他两个在令一优先级别。接着设置响应优先级可以有8种选择;假如现在同时有两个抢占式优先级别相同的中断发生,那么处理的顺序是谁的响应优先级高则谁优先进入中断,另外这点是需要注意的,如果此时进入这个中断之后又来了一个抢占式优先级相同但是响应优先级更高的中断,这时也是不会打断已有的中断的

4、设置中断

以设置串口中断为例,完整代码如下

void uart_init(u32 bound){
    GPIO_InitTypeDef GPIO_InitStructure;
	USART_InitTypeDef USART_InitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;
	 
	# a)使能USART1、GPIOA时钟 
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE);	
  
  	# b)引脚初始化
	//USART1_TX   GPIOA.9 初始化
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;	//复用为推免输出
	GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.9
   
	//USART1_RX	  GPIOA.10 初始化
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//PA10
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
	GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.10  

    # c)配置中断优先级Usart1 NVIC
    NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;//抢占式优先级为3
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;		//子优先级(响应式优先级)为3
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;			//IRQ通道使能
	NVIC_Init(&NVIC_InitStructure);	//配置
  
    # d)USART初始化设置
	USART_InitStructure.USART_BaudRate = bound;					//串口波特率
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;	//数据长度8位
	USART_InitStructure.USART_StopBits = USART_StopBits_1;		//停止位1位
	USART_InitStructure.USART_Parity = USART_Parity_No;			//无奇偶校验
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制
	USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;	//收发模式(读写都使能)
	
	# e) 初始化串口、使能串口中断、使能串口
	USART_Init(USART1, &USART_InitStructure); 		//初始化串口1
	USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);	//开启串口中断
	USART_Cmd(USART1, ENABLE);                    	//使能串口1
}

5、中断处理函数

注意 USART_IT_IDLE 和 USART_IT_RXNE 区别:文章来源地址https://www.toymoban.com/news/detail-657718.html

当接收到1个字节,会产生 USART_IT_RXNE 中断
当接收到1帧数据,会产生 USART_IT_IDLE 中断
void USART1_IRQHandler(void)                
{
	u8 Res;
	u8 clear = 0;
	
	# a)
	if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)   
	{
		Res =USART_ReceiveData(USART1);	//读取收到的数据
		TEST_RX_BUF[TEST_RX_STA++]=Res;	//将数据放入缓存
	} 
	else if(USART_GetITStatus(USART1, USART_IT_IDLE) != RESET)
	{
		clear = USART2->SR;
		clear = USART2->DR;
		clear = clear;
		TEST_RX_BUF[0] = TEST_RX_STA- 1;
		TEST_RX_STA= 1;
	} 											 
} 

到了这里,关于【STM32】进阶(一):抢占式优先级和响应式优先级(NVIC_PriorityGroupConfig)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • stm32-NVIC中断优先级管理(以古代官职角度分析)

    讲在前面的话: 博主在学习正点原子这一章节的时候很是懵,感觉摸不到门路,于是在网上找了一些相关的视频讲解,将他们的内容整合了一下,并尽量用易懂的话讲解。(本文基于stm32f103ZET6) CM3 内核支持256个中断,其中包含了 16 个内核中断和 240 个外部中断,并且具有

    2024年02月22日
    浏览(29)
  • 【STM32F407学习笔记】中断优先级管理与外部中断

    计算机系统中中断占有极其重要的地位,在嵌入式系统中更是如此。中断机制能让计算机有效合理的发挥效能和提高效率。 涉及外设 :EXIT外部中断,NVIC内嵌向量中断控制器。 计算机在执行程序的过程中,当出现异常情况或特殊情况时,计算机停止现在程序的运行,转向对

    2024年02月02日
    浏览(39)
  • 中断处理优先级和中断响应优先级的区别

      中断响应优先级是针对同时到达的中断请求先处理谁的规定。比如A、B同时向CPU发出中断请求,而中断响应优先级是AB,那么CPU就会先处理A,再处理B。   如下图:   中断处理优先级是解决中断嵌套情况下优先处理谁的问题。比如A、B两个中断的中断处理优先级是BA,

    2024年02月11日
    浏览(28)
  • 【C++进阶(六)】STL大法--栈和队列深度剖析&优先级队列&适配器原理

    💓博主CSDN主页:杭电码农-NEO💓   ⏩专栏分类:C++从入门到精通⏪   🚚代码仓库:NEO的学习日记🚚   🌹关注我🫵带你学习C++   🔝🔝 和C语言学习期间的学习顺序一样 顺序表,链表过了就是栈和队列 但是栈和队列非常特殊,它的内部结构 并不是靠自己实现的,而是一种 适配

    2024年02月08日
    浏览(30)
  • iOS开发进阶(六):Xcode14 使用信号量造成线程优先级反转问题修复

    应用 Xcode 14.1 进行项目编译时,遇到以下错误提示,导致APP线程暂停。 以上问题是由于iOS信号量造成线程优先级反转,在并发队列使用信号量会可能会造成线程优先级反转。 经过查询资料,发现是在 XCode14 上增加了工具,比如 : Thread Performance Checker ( XCode14 上默认开启的)

    2024年02月01日
    浏览(47)
  • c语言[]优先级大于*优先级

    本博文源于笔者正在学习的c语言[]优先级大于*优先级.在定义二维数组时,a+1与[]号结合后,谁的优先级更高,是本博文探讨的话题 想要看看*与[]谁的优先级更高 通过代码发现[]优先级比*号要高(a+1)[1]等价于a+2再取*号就是9了,在第二个pirintf代码中,等价于a[1][1] =6,第三个

    2024年01月20日
    浏览(39)
  • Android 音频策略(音频优先级,音频输入输入,声音优先级)

    音频设备(/system/core/include/system/audio.h) 注意: 这些设备比较常用的就是HDMI,扬声器,3.5mm圆孔耳机,USB耳机,还有蓝牙耳机。本文也主要针对这些设备的输入和输出策略做出说明。 Android音频策略主要是在 frameworks/av/services/audiopolicy/enginedefault/src/Engine.cpp中,接下来我们看一

    2024年02月04日
    浏览(42)
  • 【CSS】CSS 特性 ( CSS 优先级 | 优先级引入 | 选择器基本权重 )

    定义 CSS 样式时 , 可能出现  多个 类型相同的 规则   定义在 同一个元素上 , 如果 CSS 选择器 相同  ,  执行 CSS 层叠性  , 根据  就近原则  选择执行的样式 , 如 : 出现两个 div 标签选择器 , 都设置 color 文本颜色 ; 如果 CSS 选择器 不同 ,  则需要考虑 CSS 优先级 问题 ,  需要计

    2024年02月10日
    浏览(36)
  • 机械臂多任务逆运动学(优先级同等和存在优先级)

    我们经常使用微分运动学来计算机器人的逆运动学,对于单个任务的机械臂的逆运动学使用的是梯度投影法: 冗余机械臂求解逆运动学解——梯度投影法 但是对于多任务的逆运动学在一般的机器人学里面很少有提及,最近看到了相关的论述,于是做一下笔记整理一下。 设共

    2024年02月16日
    浏览(39)
  • Linux_进程的优先级&&环境变量&&上下文切换&&优先级队列

    什么是优先级? 指定一个进程获取某种资源的先后顺序 本质是进程获取cpu资源的优先顺序 为什么要有优先级 进程访问的资源(CPU)是有限的 操作系统关于调度和优先级的原则:分时操作系统,基本的公平,如果进程因为长时间不被调整,就造成了饥饿问题 Linux的优先级特

    2024年04月09日
    浏览(38)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包