使用GD32 MCU的过程中,大家可能会有以下疑问:中断优先级如何配置和使用?
本文将会为大家解析中断优先级分组以及中断优先级的配置使用:
  • 中断优先级分组配置

一个GD32 MCU系统需要大家明确系统中使用的中断优先级分组,避免中断优先级配置越界导致一些不符合预期的中断现象。
中断优先级分组可采用以下函数接口,其中有4个bit可用于中断优先级分组,如果全用于抢占优先级,则可以配置0-15的优先级,如果2位用于抢占,2位用于次优先级,则抢占优先级可以配置0-3,此优先级可以配置0-3。
/*!
 \brief set the priority group
 \param[in] nvic_prigroup: the NVIC priority group
 \arg NVIC_PRIGROUP_PRE0_SUB4:0 bits for pre-emption priority 4 bits for subpriority
 \arg NVIC_PRIGROUP_PRE1_SUB3:1 bits for pre-emption priority 3 bits for subpriority
 \arg NVIC_PRIGROUP_PRE2_SUB2:2 bits for pre-emption priority 2 bits for subpriority
 \arg NVIC_PRIGROUP_PRE3_SUB1:3 bits for pre-emption priority 1 bits for subpriority
 \arg NVIC_PRIGROUP_PRE4_SUB0:4 bits for pre-emption priority 0 bits for subpriority
 \param[out] none
 \retval none
*/void nvic_priority_group_set(uint32_t nvic_prigroup){
 /* set the priority group value */
 SCB->AIRCR = NVIC_AIRCR_VECTKEY_MASK | nvic_prigroup;
}
注意:如果中断优先级配置为2位抢占和2位此优先级的话,抢占优先级配置为4(二进制为100b),优先级配置越界,实际配置进去的优先级为0,最高优先级,因而明确中断优先级分组非常重要。
  • 中断优先级配置

中断优先级配置采用以下函数。
/*!
 \brief enable NVIC request
 \param[in] nvic_irq: the NVIC interrupt request, detailed in IRQn_Type
 \param[in] nvic_irq_pre_priority: the pre-emption priority needed to set
 \param[in] nvic_irq_sub_priority: the subpriority needed to set
 \param[out] none
 \retval none
*/void nvic_irq_enable(uint8_t nvic_irq, uint8_t nvic_irq_pre_priority,  uint8_t nvic_irq_sub_priority){
 uint32_t temp_priority = 0x00U, temp_pre = 0x00U, temp_sub = 0x00U;
 /* use the priority group value to get the temp_pre and the temp_sub */
 if(((SCB->AIRCR) & (uint32_t)0x700U)==NVIC_PRIGROUP_PRE0_SUB4){
 temp_pre=0U;
 temp_sub=0x4U;
 }else if(((SCB->AIRCR) & (uint32_t)0x700U)==NVIC_PRIGROUP_PRE1_SUB3){
 temp_pre=1U;
 temp_sub=0x3U;
 }else if(((SCB->AIRCR) & (uint32_t)0x700U)==NVIC_PRIGROUP_PRE2_SUB2){
 temp_pre=2U;
 temp_sub=0x2U;
 }else if(((SCB->AIRCR) & (uint32_t)0x700U)==NVIC_PRIGROUP_PRE3_SUB1){
 temp_pre=3U;
 temp_sub=0x1U;
 }else if(((SCB->AIRCR) & (uint32_t)0x700U)==NVIC_PRIGROUP_PRE4_SUB0){
 temp_pre=4U;
 temp_sub=0x0U;
 }else{
 nvic_priority_group_set(NVIC_PRIGROUP_PRE2_SUB2);
 temp_pre=2U;
 temp_sub=0x2U;
 }
 /* get the temp_priority to fill the NVIC->IP register */
 temp_priority = (uint32_t)nvic_irq_pre_priority << (0x4U - temp_pre);
 temp_priority |= nvic_irq_sub_priority &(0x0FU >> (0x4U - temp_sub));
 temp_priority = temp_priority << 0x04U;
 NVIC->IP[nvic_irq] = (uint8_t)temp_priority;
 /* enable the selected IRQ */
 NVIC->ISER[nvic_irq >> 0x05U] = (uint32_t)0x01U << (nvic_irq & (uint8_t)0x1FU);
}
nvic_irq为中断号,中断号可以通过gd32f30x.h获取,如下图所示,nvic_irq_pre_priority为抢占优先级配置,nvic_irq_sub_priority为此优先级配置,注意优先级配置要根据优先级分组进行配置,不要越界哦。


点赞(0)

评论列表 共有 0 条评论

暂无评论