STM32学习笔记——NVIC
1、设置中断分组
HAL_NVIC_SetPriorityGrouping
void HAL_NVIC_SetPriorityGrouping(uint32_t PriorityGroup)
{
/* Check the parameters */
assert_param(IS_NVIC_PRIORITY_GROUP(PriorityGroup));
/* Set the PRIGROUP[10:8] bits according to the PriorityGroup parameter value */
NVIC_SetPriorityGrouping(PriorityGroup);
}
NVIC_SetPriorityGrouping
__STATIC_INLINE void __NVIC_SetPriorityGrouping(uint32_t PriorityGroup)
{
uint32_t reg_value;
uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */
reg_value = SCB->AIRCR; /* read old register configuration */
reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */
reg_value = (reg_value |
((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) |
(PriorityGroupTmp << SCB_AIRCR_PRIGROUP_Pos) ); /* Insert write key and priority group */
SCB->AIRCR = reg_value;
}
2、设置单个向量中断抢占级和响应级
HAL_NVIC_SetPriority
- 参数
- 中断向量号
- 抢占级
- 相应级
如分组为1,根据中断分组表中,得到抢占级1位,响应级3位, 所以响应级最大为7.
void HAL_NVIC_SetPriority(IRQn_Type IRQn, uint32_t PreemptPriority, uint32_t SubPriority)
{
uint32_t prioritygroup = 0x00;
/* Check the parameters */
assert_param(IS_NVIC_SUB_PRIORITY(SubPriority));
assert_param(IS_NVIC_PREEMPTION_PRIORITY(PreemptPriority));
prioritygroup = NVIC_GetPriorityGrouping();
NVIC_SetPriority(IRQn, NVIC_EncodePriority(prioritygroup, PreemptPriority, SubPriority));
}
NVIC_SetPriority
把中断组、响应级别、抢占级别存入寄存器。
__STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
{
if ((int32_t)(IRQn) >= 0)
{
NVIC->IP[((uint32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL);
}
else
{
SCB->SHP[(((uint32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL);
}
}
3、设置单个中断使能信息(中断屏蔽)
每个中断向量在寄存器中表示的信息, ISER[8]八个寄存器,每个是32位,也就是256个中断, ISER[0]的0-31bit分别对应0-31个中断。
typedef struct
{
__IO uint32_t ISER[8]; //中断使能寄存器组//
uint32_t RESERVED0[24];
__IO uint32_t ICER[8]; //中断失能寄存器组//
uint32_t RSERVED1[24];
__IO uint32_t ISPR[8]; //中断挂起寄存器组//
uint32_t RESERVED2[24];
__IO uint32_t ICPR[8]; //中断解挂寄存器组//
uint32_t RESERVED3[24];
__IO uint32_t IABR[8]; //中断激活标志位寄存器组// 是1代表中断正在执行
uint32_t RESERVED4[56];
__IO uint8_t IP[240]; //中断优先级控制的寄存器组//
uint32_t RESERVED5[644];
__O uint32_t STIR;
}
NVIC_Type;
HAL_NVIC_EnableIRQ
void HAL_NVIC_EnableIRQ(IRQn_Type IRQn)
{
/* Check the parameters */
assert_param(IS_NVIC_DEVICE_IRQ(IRQn));
/* Enable interrupt */
NVIC_EnableIRQ(IRQn);
}
HAL_NVIC_DisableIRQ
void HAL_NVIC_DisableIRQ(IRQn_Type IRQn)
{
/* Check the parameters */
assert_param(IS_NVIC_DEVICE_IRQ(IRQn));
/* Disable interrupt */
NVIC_DisableIRQ(IRQn);
}
HAL_NVIC_SetPendingIRQ
void HAL_NVIC_SetPendingIRQ(IRQn_Type IRQn)
{
/* Check the parameters */
assert_param(IS_NVIC_DEVICE_IRQ(IRQn));
/* Set interrupt pending */
NVIC_SetPendingIRQ(IRQn);
}
HAL_NVIC_GetPendingIRQ
uint32_t HAL_NVIC_GetPendingIRQ(IRQn_Type IRQn)
{
/* Check the parameters */
assert_param(IS_NVIC_DEVICE_IRQ(IRQn));
/* Return 1 if pending else 0 */
return NVIC_GetPendingIRQ(IRQn);
}
HAL_NVIC_ClearPendingIRQ
void HAL_NVIC_ClearPendingIRQ(IRQn_Type IRQn)
{
/* Check the parameters */
assert_param(IS_NVIC_DEVICE_IRQ(IRQn));
/* Clear pending interrupt */
NVIC_ClearPendingIRQ(IRQn);
}
HAL_NVIC_GetActive
uint32_t HAL_NVIC_GetActive(IRQn_Type IRQn)
{
/* Return 1 if active else 0 */
return NVIC_GetActive(IRQn);
}
每个中断我们都可以设置中断组、抢占级、响应级别。也可以屏蔽中断(也就是中断来了也不起作用)
配置中断及优先级
- 使能uart
- 开启中断,设置中断抢占级
- 使能中断接收函数
- 编写中断服务程序
当没发生一次中断就会执行中断服务程序一次。