博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
stm32 设置systick中断抢先式优先级
阅读量:4153 次
发布时间:2019-05-25

本文共 2547 字,大约阅读时间需要 8 分钟。

最近使用STM32时希望将systick的中断优先级降低,但是CMSIS里给出的例子都是类似

    NVIC_InitStructure.NVIC_IRQChannel = TIM1_UP_IRQn;    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;    NVIC_Init(&NVIC_InitStructure);
还是没有配置systick。

后来阅读CM3的技术参考手册,讲解了NVIC的配置。

中断分为内核中断和芯片的中断,配置的寄存器位置不同。芯片的中断配置在NVIC的IP内,内核的中断配置在SCB内。

可以直接调用core_cm3.h里的函数

static __INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority){  if(IRQn < 0) {    SCB->SHP[((uint32_t)(IRQn) & 0xF)-4] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff); } /* set Priority for Cortex-M3 System Interrupts */  else {    NVIC->IP[(uint32_t)(IRQn)] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff);    }        /* set Priority for device specific Interrupts  */}
这个函数实现了两类中断优先级的配置。

但是直观上来看看不到抢先式优先级与子优先级。

首先,配置优先级组,可以使用固件库的程序,也可以用core_cm3.h的函数。

void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup){  /* Set the PRIGROUP[10:8] bits according to NVIC_PriorityGroup value */  SCB->AIRCR = AIRCR_VECTKEY_MASK | NVIC_PriorityGroup;}

static __INLINE void NVIC_SetPriorityGrouping(uint32_t PriorityGroup){  uint32_t reg_value;  uint32_t PriorityGroupTmp = (PriorityGroup & 0x07);                         /* only values 0..7 are used          */    reg_value  =  SCB->AIRCR;                                                   /* read old register configuration    */  reg_value &= ~(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk);             /* clear bits to change               */  reg_value  =  (reg_value                       |                (0x5FA << SCB_AIRCR_VECTKEY_Pos) |                 (PriorityGroupTmp << 8));                                     /* Insert write key and priorty group */  SCB->AIRCR =  reg_value;}
参数范围为0~7,具体如下

随后配置各个中断的优先级,对于外设的中断可以使用固件库的程序,比较直观。如最前面所给出的例子,但是根据其实现,是不能够用来配置内核中断的,例如

NVIC_InitStructure.NVIC_IRQChannel = SysTick_IRQn;    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;    NVIC_Init(&NVIC_InitStructure);
这是错误的,因为内部使用IRQn寻址,而SysTick_IRQn为-1.

所以对于Sysick使用core_cm3.h的函数

NVIC_SetPriority(SysTick_IRQn, 4);
这时不能显式的看出抢先式优先级与子优先级,写入的优先级需要根据优先级组的配置来选择。

NVIC_SetPriority(SysTick_IRQn, n);n=0x00~0x03 设置Systick为抢占优先级0n=0x04~0x07 设置Systick为抢占优先级1n=0x08~0x0B 设置Systick为抢占优先级2n=0x0C~0x0F 设置Systick为抢占优先级3

NVIC_SetPriority函数指定中断优先级的寄存器位(STM32只用4位来表示优先级)的数据,例如中断优先级组设置为了2,即高2位用于指定抢占式优先级,低2位用于指定响应优先级,0x00~0x03高2位为0,所以抢占优先级为0;0x04~0x07高2位为1,所以抢占优先级为1,以此类推。 

转载地址:http://pbmti.baihongyu.com/

你可能感兴趣的文章
自定义控件:动态获取控件的高
查看>>
第三方开源库:nineoldandroid:ValueAnimator 动态设置textview的高
查看>>
第三方SDK:百度地图SDK的使用
查看>>
Android studio_迁移Eclipse项目到Android studio
查看>>
JavaScript setTimeout() clearTimeout() 方法
查看>>
CSS border 属性及用border画各种图形
查看>>
转载知乎-前端汇总资源
查看>>
JavaScript substr() 方法
查看>>
JavaScript slice() 方法
查看>>
JavaScript substring() 方法
查看>>
HTML 5 新的表单元素 datalist keygen output
查看>>
(转载)正确理解cookie和session机制原理
查看>>
jQuery ajax - ajax() 方法
查看>>
将有序数组转换为平衡二叉搜索树
查看>>
最长递增子序列
查看>>
从一列数中筛除尽可能少的数,使得从左往右看这些数是从小到大再从大到小...
查看>>
判断一个整数是否是回文数
查看>>
腾讯的一道面试题—不用除法求数字乘积
查看>>
素数算法
查看>>
java多线程环境单例模式实现详解
查看>>