COTEX-M内核中断控制

Cotex-M3 和 M4的 NVIC 最多支持 240个 IRQ(中断请求)、1一个不可屏蔽中断(NMI)、1个Systick(滴答定时器)中断和多个系统异常
ST使用16个优先级
STM32关于中断的寄存器在NVIC 和 SCB中

typedef struct
{
		__IOM uint32_t ISER[8U];               /*!< Offset: 0x000 (R/W)  Interrupt Set Enable Register */
		//以上为8个32位寄存器,为240个中断的使能
   		uint32_t RESERVED0[24U];
		__IOM uint32_t ICER[8U];               /*!< Offset: 0x080 (R/W)  Interrupt Clear Enable Register */
		//以上为中断0-31的除能寄存器
        uint32_t RSERVED1[24U];
 		 __IOM uint32_t ISPR[8U];               /*!< Offset: 0x100 (R/W)  Interrupt Set Pending Register */
 		 //以上为中断0-31的悬起寄存器
        uint32_t RESERVED2[24U];
 		 __IOM uint32_t ICPR[8U];               /*!< Offset: 0x180 (R/W)  Interrupt Clear Pending Register */
 		 //以上为中断0-31的解悬寄存器
        uint32_t RESERVED3[24U];
  		__IOM uint32_t IABR[8U];               /*!< Offset: 0x200 (R/W)  Interrupt Active bit Register */
  		//中断活动寄存器
        uint32_t RESERVED4[56U];
 		 __IOM uint8_t  IP[240U];               /*!< Offset: 0x300 (R/W)  Interrupt Priority Register (8Bit wide) */
 		 //每个外部中断的优先级分组设置寄存器,每个寄存器占用8位,4个相邻的优先级寄存器拼成一个32位寄存器
        uint32_t RESERVED5[644U];
  		__OM  uint32_t STIR;                   /*!< Offset: 0xE00 ( /W)  Software Trigger Interrupt Register */
  		//以上为软件触发中断寄存器
  		
}  NVIC_Type;

在这里插入图片描述
在这里插入图片描述
编号 0,1, 2,3不可更改

在这里插入图片描述
STM32只是用高四位表达优先级级数,所以最多16级分组

在这里插入图片描述
7对应着STM32的组0

如何设置为哪个优先级分组

在这里插入图片描述
上图地址不一定正确
STM32通过这一个寄存器设置中断优先级分组,使用3位控制5个分组

在这里插入图片描述

注: FREERTOS中着重设置 PendSV 和 SysTick的优先级
在这里插入图片描述
如何设置?
在port.c中,代码如下:

/***************************************************************************************************************/
/*                                FreeRTOS与中断有关的配置选项                                                  */
/***************************************************************************************************************/
#ifdef __NVIC_PRIO_BITS
	#define configPRIO_BITS       		__NVIC_PRIO_BITS
#else
	#define configPRIO_BITS       		4                  
#endif

#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY			15                      //中断最低优先级
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY	5                       //系统可管理的最高中断优先级
#define configKERNEL_INTERRUPT_PRIORITY 		( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
#define configMAX_SYSCALL_INTERRUPT_PRIORITY 	( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
#define portNVIC_PENDSV_PRI					( ( ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY ) << 16UL )
#define portNVIC_SYSTICK_PRI				( ( ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY ) << 24UL )
#define portNVIC_SYSPRI2_REG				( * ( ( volatile uint32_t * ) 0xe000ed20 ) ) 
//portNVIC_SYSPRI2_REG的地址对应上图的系统异常优先级 0xE000_ED20(四个八位合成一个32位的寄存器)       	
        //at BaseType_t xPortStartScheduler()
    		
		/* Make PendSV and SysTick the lowest priority interrupts. */
		portNVIC_SYSPRI2_REG |= portNVIC_PENDSV_PRI;
		portNVIC_SYSPRI2_REG |= portNVIC_SYSTICK_PRI;

中断屏蔽寄存器

进入临界段代码保护时,屏蔽其他中断

  1. PRIMASK寄存器:用于除能NMI和硬FAULT之外的所有异常
    在这里插入图片描述
    使能:

    //关闭所有中断(但是不包括fault和NMI中断)
    __asm void INTX_DISABLE(void)
    {
    CPSID I
    BX LR
    }
    除能:

    //开启所有中断
    __asm void INTX_ENABLE(void)
    {
    CPSIE I
    BX LR
    }

  2. FAULTMASK寄存器:
    屏蔽比-1级数更低的中断优先级(硬FAULT也被屏蔽),使用方法和上面的PRIMASK一样,对应的寄存器设1(使能)或者设0(除能)

  3. BASEPRI寄存器:
    屏蔽比优先级没它高的中断(中断0~15,数字越大,优先级越低,0最先,15最后)
    比如寄存器的值是 0x30(STM32只是用高四位),所以0~2优先级的不被屏蔽, 3~15级的将被屏蔽,使能和除能的代码如下:

使能:

static portFORCE_INLINE void vPortSetBASEPRI( uint32_t ulBASEPRI )
{
	__asm
	{
		/* Barrier instructions are not used as this function is only used to
		lower the BASEPRI value. */
		msr basepri, ulBASEPRI
	}
}

除能:

static portFORCE_INLINE void vPortClearBASEPRIFromISR( void )
{
	__asm
	{
		/* Set BASEPRI to 0 so no interrupts are masked.  This function is only
		used to lower the mask in an interrupt, so memory barriers are not 
		used. */
		msr basepri, #0
	}
}

在这里插入图片描述
FREERTOS中不能使用0~ 4优先级的中断,只能使用5~15的中断(带ISR的函数可以使用这些优先级)

PENDService中断

通过向ICSR寄存器bit28置1触发
在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值