STM32中断优先级配置实战教程

版权申诉
0 下载量 188 浏览量 更新于2024-10-23 收藏 14KB RAR 举报
资源摘要信息:"stm32-NVIC_PriorityGroupConfig.rar_stm32" 本资源聚焦于STM32微控制器中的嵌套向量中断控制器(NVIC)的优先级分组配置。STM32系列微控制器广泛应用于各种嵌入式系统中,而NVIC作为STM32核心的组成部分,负责管理中断请求并确保响应的优先级。优先级分组(Priority Grouping)是STM32中断系统中一项重要的配置,它允许系统设计师对多个中断源进行优先级设置,以满足实时性和系统效率的需求。 在本资源中,将通过一个应用开发例子深入探讨STM32 NVIC_PriorityGroupConfig的应用。这个例子将展示如何在STM32的固件库中配置NVIC的优先级分组,以便更有效地管理中断服务。 STM32微控制器由STMicroelectronics(意法半导体)生产,其高性能、高集成度、低功耗和丰富的外设支持是其成为工业级应用的首选微控制器之一。STM32家族涵盖了广泛的系列,包括从低成本的Cortex-M0核心到高性能的Cortex-M4核心,以及支持浮点运算的Cortex-M7核心。 NVIC是Cortex-M核心特有的中断控制器,它在STM32微控制器中的作用至关重要。它不仅提供了中断请求(IRQ)的管理,还提供了优先级管理,使得在多个中断同时发生时,可以按照预设的优先级顺序进行处理。NVIC支持多达256个中断优先级级别,但实际可用的级别数量取决于优先级分组的配置。 优先级分组的概念是指将NVIC的优先级字段分为抢占优先级和子优先级两部分。在STM32中,可以通过调用特定的API函数来设置NVIC的优先级分组,例如在STM32标准固件库中,使用函数NVIC_PriorityGroupConfig()来配置优先级分组。优先级分组的配置将影响中断处理的灵活性和实时性。 NVIC_PriorityGroupConfig()函数通常用于设置中断优先级分组的配置,其参数一般由NVIC_PriorityGroup枚举类型给出,该枚举定义了分组的类型,例如:NVIC_PriorityGroup_0到NVIC_PriorityGroup_4等。选择不同的分组类型将决定抢占优先级和子优先级的数量及分配方式。 例如,在某些配置中,可以将优先级字段完全用于抢占优先级,而在另一些配置中,可以将其拆分为几个抢占优先级和几个子优先级。这种灵活性对于设计复杂的应用程序来说非常重要,因为它允许系统设计师根据应用场景的特定需求来优化中断管理。 在实际应用中,优先级分组配置通常在系统初始化阶段完成,这确保了在中断服务程序编写之前,中断的优先级就已经被正确地设置了。之后,开发者可以依据优先级分组来配置各个中断源的优先级,确保关键中断得到及时处理,同时又不阻塞其他较低优先级的中断服务。 本资源通过实例演示了如何使用STM32的NVIC_PriorityGroupConfig函数来配置优先级分组,通过这个例子,开发者可以更深入地理解如何在STM32的固件开发中实现高效的中断管理。这对于需要在嵌入式系统中处理多个并发任务的应用程序尤为重要,有助于提升系统响应能力和整体性能。

#include "stm32f10x.h" /* Private typedef -----------------------------------------------------------*/ /* Private define ------------------------------------------------------------*/ void GPIO_Configuration(void); void NVIC_Configuration(void); void EXTI_Configuration(void); int main(void) { GPIO_Configuration(); NVIC_Configuration(); EXTI_Configuration(); GPIO_SetBits(GPIOC,GPIO_Pin_0);//GPIOC Pin0输出高电平即熄灭LED while(1) { } } void GPIO_Configuration() { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);//使能AFIO时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//使能GPIOA时钟 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;//可以以或方式添加多个引脚 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;//下拉输入 GPIO_InitStructure.GPIO_Speed= GPIO_Speed_2MHz;//配置为输入模式时,可不配置速度 GPIO_Init(GPIOA, &GPIO_InitStructure);//以GPIO_InitStructure变量的值作为配置信息,初始化GPIOA RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE,ENABLE);//使能GPIOE时钟 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;//可以以或方式添加多个引脚 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;//上拉输入 GPIO_InitStructure.GPIO_Speed= GPIO_Speed_2MHz;//配置为输入模式时,可不配置速度 GPIO_Init(GPIOE, &GPIO_InitStructure);//以GPIO_InitStructure变量的值作为配置信息,初始化GPIOE RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);//使能GPIOC时钟 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;//可以以或方式添加多个引脚 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//推挽输出 GPIO_InitStructure.GPIO_Speed= GPIO_Speed_2MHz;//引脚的输出速度为2MHz GPIO_Init(GPIOC, &GPIO_InitStructure);//以GPIO_InitStructure变量的值作为配置信息,初始化GPIOC } void NVIC_Configuration() { NVIC_InitTypeDef NVIC_InitStructure; NVIC_SetVectorTable(NVIC_VectTab_FLASH,0x0); NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); NVIC_InitStructure.NVIC_IRQChannel=EXTI0_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0; NVIC_InitStructure.NVIC_IRQChannelSubPriority=0; NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE; NVIC_Init(&NVIC_InitStructure); NVIC_InitStructure.NVIC_IRQChannel=EXTI3_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0; NVIC_InitStructure.NVIC_IRQChannelSubPriority=0; NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE; NVIC_Init(&NVIC_InitStructure); } void EXTI_Configuration() { EXTI_InitTypeDef EXTI_InitStructure; EXTI_InitStructure.EXTI_Line=EXTI_Line0|EXTI_Line3; EXTI_InitStructure.EXTI_Mode=EXTI_Mode_Interrupt; EXTI_InitStructure.EXTI_Trigger=EXTI_Trigger_Rising_Falling ; EXTI_InitStructure.EXTI_LineCmd=ENABLE; EXTI_Init(&EXTI_InitStructure); GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0);// GPIO_EXTILineConfig(GPIO_PortSourceGPIOE, GPIO_PinSource3);// }根据程序画一个流程图

2023-06-01 上传
2023-07-15 上传

#include "stm32f10x.h" // Device header int16_t Encoder_Num; void Encoder_Init (void) { RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE); GPIO_InitTypeDef GPIO_Initstructure; GPIO_Initstructure.GPIO_Mode=GPIO_Mode_IPU; GPIO_Initstructure.GPIO_Pin=GPIO_Pin_0|GPIO_Pin_1; GPIO_Initstructure.GPIO_Speed=GPIO_Speed_50MHz; GPIO_Init(GPIOB,&GPIO_Initstructure); GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource0|GPIO_PinSource1); EXTI_InitTypeDef EXTI_Initstructure; EXTI_Initstructure.EXTI_Line=EXTI_Line0|EXTI_Line1; EXTI_Initstructure.EXTI_LineCmd=ENABLE; EXTI_Initstructure.EXTI_Mode=EXTI_Mode_Interrupt; EXTI_Initstructure.EXTI_Trigger=EXTI_Trigger_Falling; EXTI_Init(&EXTI_Initstructure); NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); NVIC_InitTypeDef NVIC_Initstructure; NVIC_Initstructure.NVIC_IRQChannel=EXTI0_IRQn; NVIC_Initstructure.NVIC_IRQChannelCmd=ENABLE; NVIC_Initstructure.NVIC_IRQChannelPreemptionPriority=1; NVIC_Initstructure.NVIC_IRQChannelSubPriority=1; NVIC_Init(&NVIC_Initstructure); NVIC_Initstructure.NVIC_IRQChannel=EXTI1_IRQn; NVIC_Initstructure.NVIC_IRQChannelCmd=ENABLE; NVIC_Initstructure.NVIC_IRQChannelPreemptionPriority=2; NVIC_Initstructure.NVIC_IRQChannelSubPriority=2; NVIC_Init(&NVIC_Initstructure); } int Encoder_get() { int16_t temp; temp=Encoder_Num; Encoder_Num=0; return temp; } void EXTI0_IRQHandler () { if (EXTI_GetITStatus(EXTI_Line0)==SET) { if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_0)==0) { if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_1)==1) { Encoder_Num++; } } EXTI_ClearITPendingBit(EXTI_Line0); } } void EXTI1_IRQHandler () { if (EXTI_GetITStatus(EXTI_Line1)==SET) { if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_1)==0) { if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_0)==1) { Encoder_Num--; } } EXTI_ClearITPendingBit(EXTI_Line1); } } 中断1可以出发但是中断0不能触发

2023-07-16 上传
2023-06-03 上传
2023-07-15 上传