微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > stm32 设置systick中断抢先式优先级

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

时间:11-28 来源:互联网 点击:
最近使用STM32时希望将systick的中断优先级降低,但是CMSIS里给出的例子都是类似

[plain]view plaincopy

  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里的函数

[cpp]view plaincopy

  1. static__INLINEvoidNVIC_SetPriority(IRQn_TypeIRQn,uint32_tpriority)
  2. {
  3. if(IRQn0){
  4. SCB->SHP[((uint32_t)(IRQn)&0xF)-4]=((priority(8-__NVIC_PRIO_BITS))&0xff);}
  5. else{
  6. NVIC->IP[(uint32_t)(IRQn)]=((priority(8-__NVIC_PRIO_BITS))&0xff);}
  7. }

这个函数实现了两类中断优先级的配置。

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

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

[cpp]view plaincopy

  1. voidNVIC_PriorityGroupConfig(uint32_tNVIC_PriorityGroup)
  2. {
  3. SCB->AIRCR=AIRCR_VECTKEY_MASK|NVIC_PriorityGroup;
  4. }

[cpp]view plaincopy

  1. static__INLINEvoidNVIC_SetPriorityGrouping(uint32_tPriorityGroup)
  2. {
  3. uint32_treg_value;
  4. uint32_tPriorityGroupTmp=(PriorityGroup&0x07);
  5. reg_value=SCB->AIRCR;
  6. reg_value&=~(SCB_AIRCR_VECTKEY_Msk|SCB_AIRCR_PRIGROUP_Msk);
  7. reg_value=(reg_value|
  8. (0x5FASCB_AIRCR_VECTKEY_Pos)|
  9. (PriorityGroupTmp8));
  10. SCB->AIRCR=reg_value;
  11. }

参数范围为0~7,具体如下

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

[cpp]view plaincopy

  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的函数

[cpp]view plaincopy

  1. NVIC_SetPriority(SysTick_IRQn,4);

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

[cpp]view plaincopy

  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,以此类推。

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top