STM32之NVIC中断优先级的介绍
程序员文章站
2024-02-25 14:51:51
...
2018/4/9
STM32
1.说在前面
1.中断:中断就是CPU在处理一件事的时候,遇到紧急情况,所以就去响应而处理另外一件事(粗略介绍)
2.对于51而言,只有5个中断源,所以难度不算太大,但是,对于CM3内核支持256个中断(16个内核中断加240个内部中断)
stm32F103而言,有着60会让可屏蔽中断,所以相对来说比较复杂
2.对于中断的部分寄存器的简单介绍
typedef struct
{
__IO uint32_t ISER[8]; /*!< Offset: 0x000 Interrupt Set Enable Register */
uint32_t RESERVED0[24];
__IO uint32_t ICER[8]; /*!< Offset: 0x080 Interrupt Clear Enable Register */
uint32_t RSERVED1[24];
__IO uint32_t ISPR[8]; /*!< Offset: 0x100 Interrupt Set Pending Register */
uint32_t RESERVED2[24];
__IO uint32_t ICPR[8]; /*!< Offset: 0x180 Interrupt Clear Pending Register */
uint32_t RESERVED3[24];
__IO uint32_t IABR[8]; /*!< Offset: 0x200 Interrupt Active bit Register */
uint32_t RESERVED4[56];
__IO uint8_t IP[240]; /*!< Offset: 0x300 Interrupt Priority Register (8Bit wide) */
uint32_t RESERVED5[644];
__O uint32_t STIR; /*!< Offset: 0xE00 Software Trigger Interrupt Register */
} NVIC_Type;
ISER[8]:中断使能寄存器,在stm32F103中使用了ISER[0](bit0-bit31对应着中断0到31),ISER[1](bit0到bit27 对应着中断32到59)
ICER[8]:设置ICER来实现除能操作
ISPR[8]:中断挂起寄存器,每个位和ISER[8]一致,将寄存器置于1则中断挂起,然后实现更高级或同级的中断,写0无效
ICPR[8]:中断解挂控制寄存器,和ISPR[8]进行对应,对相应寄存器进行解挂
IP[240]:中断优先级控制寄存器组
3.STM32的中断分组
1.通过配置SCB->AIRCR来处理
2.关于抢占优先级和响应优先级的介绍
1.对于抢占优先级和响应优先级,相对设置的数值越低,则相对更高
2.对于抢占优先级不同而言,优先级越高,可以在抢占优先级低的位置进行中断、
3.对于抢占优先级相同,但是响应优先级不同而言,响应优先级不能实现嵌套的中断,但是可以实现中断的先后顺序,在响应优先级高的位置则先进行中断
3.关于中断分组的库函数设置方法
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;
}
4.中断函数初始化的库函数设置
’
void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct)
{
uint32_t tmppriority = 0x00, tmppre = 0x00, tmpsub = 0x0F;
/* Check the parameters */
assert_param(IS_FUNCTIONAL_STATE(NVIC_InitStruct->NVIC_IRQChannelCmd));
assert_param(IS_NVIC_PREEMPTION_PRIORITY(NVIC_InitStruct->NVIC_IRQChannelPreemptionPriority));
assert_param(IS_NVIC_SUB_PRIORITY(NVIC_InitStruct->NVIC_IRQChannelSubPriority));
if (NVIC_InitStruct->NVIC_IRQChannelCmd != DISABLE)
{
/* Compute the Corresponding IRQ Priority --------------------------------*/
tmppriority = (0x700 - ((SCB->AIRCR) & (uint32_t)0x700))>> 0x08;
tmppre = (0x4 - tmppriority);
tmpsub = tmpsub >> tmppriority;
tmppriority = (uint32_t)NVIC_InitStruct->NVIC_IRQChannelPreemptionPriority << tmppre;
tmppriority |= NVIC_InitStruct->NVIC_IRQChannelSubPriority & tmpsub;
tmppriority = tmppriority << 0x04;
NVIC->IP[NVIC_InitStruct->NVIC_IRQChannel] = tmppriority;
/* Enable the Selected IRQ Channels --------------------------------------*/
NVIC->ISER[NVIC_InitStruct->NVIC_IRQChannel >> 0x05] =
(uint32_t)0x01 << (NVIC_InitStruct->NVIC_IRQChannel & (uint8_t)0x1F);
}
else
{
/* Disable the Selected IRQ Channels -------------------------------------*/
NVIC->ICER[NVIC_InitStruct->NVIC_IRQChannel >> 0x05] =
(uint32_t)0x01 << (NVIC_InitStruct->NVIC_IRQChannel & (uint8_t)0x1F);
}
}
就像设置GPIO口一样,以设置结构体的方法来实现初始化
5.明天准备学习一下外部中断函数,用上今天的知识
上一篇: 一步步搭建ssh框架