你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

stm32 设置systick中断抢先式优先级

[复制链接]
Longmiao 发布时间:2017-9-30 13:29
最近使用STM32时希望将systick的中断优先级降低,但是CMSIS里给出的例子都是类似
  1. NVIC_InitStructure.NVIC_IRQChannel = TIM1_UP_IRQn;  
  2.     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;  
  3.     NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;  
  4.     NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;  
  5.     NVIC_Init(&NVIC_InitStructure);  
复制代码

还是没有配置systick。


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

中断分为内核中断和芯片的中断,配置的寄存器位置不同。芯片的中断配置在NVIC的IP内,内核的中断配置在SCB内。
可以直接调用core_cm3.h里的函数
  1. static __INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)  
  2. {  
  3.     if(IRQn < 0) {  
  4.         SCB->SHP[((uint32_t)(IRQn) & 0xF)-4] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff); } /* set Priority for Cortex-M3 System Interrupts */
复制代码
这个函数实现了两类中断优先级的配置。

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

首先,配置优先级组,可以使用固件库的程序,也可以用core_cm3.h的函数。
  1. void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup)  
  2. {  
  3.     /* Set the PRIGROUP[10:8] bits according to NVIC_PriorityGroup value */  
  4.     SCB->AIRCR = AIRCR_VECTKEY_MASK | NVIC_PriorityGroup;  
  5. }
复制代码
  1. static __INLINE void NVIC_SetPriorityGrouping(uint32_t PriorityGroup)  
  2.     {  
  3.     uint32_t reg_value;  
  4.     uint32_t PriorityGroupTmp = (PriorityGroup & 0x07);                         /* only values 0..7 are used          */  
  5.    
  6.     reg_value  =  SCB->AIRCR;                                                   /* read old register configuration    */  
  7.     reg_value &= ~(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk);             /* clear bits to change               */  
  8.     reg_value  =  (reg_value                       |  
  9.                 (0x5FA << SCB_AIRCR_VECTKEY_Pos) |   
  10.                 (PriorityGroupTmp << 8));                                     /* Insert write key and priorty group */  
  11.     SCB->AIRCR =  reg_value;  
  12. }  
复制代码

参数范围为0~7,具体如下
1342096520_7284.png

随后配置各个中断的优先级,对于外设的中断可以使用固件库的程序,比较直观。如最前面所给出的例子,但是根据其实现,是不能够用来配置内核中断的,例如
  1. NVIC_InitStructure.NVIC_IRQChannel = SysTick_IRQn;  
  2. NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;  
  3. NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;  
  4. NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;  
  5. NVIC_Init(&NVIC_InitStructure);  
复制代码
这是错误的,因为内部使用IRQn寻址,而SysTick_IRQn为-1.

所以对于Sysick使用core_cm3.h的函数
  1. NVIC_SetPriority(SysTick_IRQn, 4);  
复制代码
这时不能显式的看出抢先式优先级与子优先级,写入的优先级需要根据优先级组的配置来选择。
  1. NVIC_SetPriority(SysTick_IRQn, n);  
  2. n=0x00~0x03 设置Systick为抢占优先级0  
  3. n=0x04~0x07 设置Systick为抢占优先级1  
  4. n=0x08~0x0B 设置Systick为抢占优先级2  
  5. n=0x0C~0x0F 设置Systick为抢占优先级3   
复制代码
NVIC_SetPriority函数指定中断优先级的寄存器位(STM32只用4位来表示优先级)的数据,例如中断优先级组设置为了2,即高2位用于指定抢占式优先级,低2位用于指定响应优先级,0x00~0x03高2位为0,所以抢占优先级为0;0x04~0x07高2位为1,所以抢占优先级为1,以此类推。

评分

参与人数 1 ST金币 +6 收起 理由
MrJiu + 6 很给力!

查看全部评分

收藏 1 评论0 发布时间:2017-9-30 13:29

举报

0个回答

所属标签

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版