stm32 设置systick中断抢先式优先级
2016-07-22 12:46
489 查看
链接地址:http://blog.csdn.net/sunjiajiang/article/details/7741715
最近使用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);
![](http://static.blog.csdn.net/images/save_snippets.png)
后来阅读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 */
}
![](http://static.blog.csdn.net/images/save_snippets.png)
但是直观上来看看不到抢先式优先级与子优先级。
首先,配置优先级组,可以使用固件库的程序,也可以用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;
}
![](http://static.blog.csdn.net/images/save_snippets.png)
或
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;
}
![](http://static.blog.csdn.net/images/save_snippets.png)
![](http://my.csdn.net/uploads/201207/12/1342096520_7284.png)
随后配置各个中断的优先级,对于外设的中断可以使用固件库的程序,比较直观。如最前面所给出的例子,但是根据其实现,是不能够用来配置内核中断的,例如
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);
![](http://static.blog.csdn.net/images/save_snippets.png)
所以对于Sysick使用core_cm3.h的函数
NVIC_SetPriority(SysTick_IRQn, 4);
![](http://static.blog.csdn.net/images/save_snippets_01.png)
NVIC_SetPriority(SysTick_IRQn, n);
n=0x00~0x03 设置Systick为抢占优先级0
n=0x04~0x07 设置Systick为抢占优先级1
n=0x08~0x0B 设置Systick为抢占优先级2
n=0x0C~0x0F 设置Systick为抢占优先级3
![](http://static.blog.csdn.net/images/save_snippets.png)
NVIC_SetPriority函数指定中断优先级的寄存器位(STM32只用4位来表示优先级)的数据,例如中断优先级组设置为了2,即高2位用于指定抢占式优先级,低2位用于指定响应优先级,0x00~0x03高2位为0,所以抢占优先级为0;0x04~0x07高2位为1,所以抢占优先级为1,以此类推。
链接地址:http://blog.csdn.net/sunjiajiang/article/details/7741715
最近使用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);
![](http://static.blog.csdn.net/images/save_snippets.png)
<span style="font-size:14px;"><span style="font-family:KaiTi_GB2312;font-size:18px;"> 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);</span></span>还是没有配置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 */
}
![](http://static.blog.csdn.net/images/save_snippets.png)
<span style="font-size:14px;"><span style="font-family:KaiTi_GB2312;font-size:18px;">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 */ }</span></span>这个函数实现了两类中断优先级的配置。
但是直观上来看看不到抢先式优先级与子优先级。
首先,配置优先级组,可以使用固件库的程序,也可以用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;
}
![](http://static.blog.csdn.net/images/save_snippets.png)
<span style="font-size:14px;"><span style="font-family:KaiTi_GB2312;font-size:18px;">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; }</span></span>
或
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;
}
![](http://static.blog.csdn.net/images/save_snippets.png)
<span style="font-size:14px;"><span style="font-family:KaiTi_GB2312;font-size:18px;">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; }</span></span>参数范围为0~7,具体如下
![](http://my.csdn.net/uploads/201207/12/1342096520_7284.png)
随后配置各个中断的优先级,对于外设的中断可以使用固件库的程序,比较直观。如最前面所给出的例子,但是根据其实现,是不能够用来配置内核中断的,例如
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);
![](http://static.blog.csdn.net/images/save_snippets.png)
<span style="font-size:14px;"><span style="font-family:KaiTi_GB2312;font-size:18px;"> 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);</span></span>这是错误的,因为内部使用IRQn寻址,而SysTick_IRQn为-1.
所以对于Sysick使用core_cm3.h的函数
NVIC_SetPriority(SysTick_IRQn, 4);
![](http://static.blog.csdn.net/images/save_snippets_01.png)
<span style="font-size:14px;"><span style="font-family:KaiTi_GB2312;font-size:18px;">NVIC_SetPriority(SysTick_IRQn, 4);</span></span>这时不能显式的看出抢先式优先级与子优先级,写入的优先级需要根据优先级组的配置来选择。
NVIC_SetPriority(SysTick_IRQn, n);
n=0x00~0x03 设置Systick为抢占优先级0
n=0x04~0x07 设置Systick为抢占优先级1
n=0x08~0x0B 设置Systick为抢占优先级2
n=0x0C~0x0F 设置Systick为抢占优先级3
![](http://static.blog.csdn.net/images/save_snippets.png)
<span style="font-size:14px;"><span style="font-family:KaiTi_GB2312;font-size:18px;">NVIC_SetPriority(SysTick_IRQn, n); n=0x00~0x03 设置Systick为抢占优先级0 n=0x04~0x07 设置Systick为抢占优先级1 n=0x08~0x0B 设置Systick为抢占优先级2 n=0x0C~0x0F 设置Systick为抢占优先级3 </span></span>
NVIC_SetPriority函数指定中断优先级的寄存器位(STM32只用4位来表示优先级)的数据,例如中断优先级组设置为了2,即高2位用于指定抢占式优先级,低2位用于指定响应优先级,0x00~0x03高2位为0,所以抢占优先级为0;0x04~0x07高2位为1,所以抢占优先级为1,以此类推。
相关文章推荐
- java生成EXCEL表单简单demo (未测试)
- 行星运动的研究 —— 月球
- Java二维码的解码和编码(未测试)
- 基于Metronic的Bootstrap开发框架经验总结(10)--优化Bootstrap图标管理
- Comments
- 单源最短路径SPFA算法-邻接矩阵
- Hibernate中,Many2One的基于注解Annotation的实现
- Java实现DES加密解密代码(未测试)
- 预编译与宏
- GitHub 中国区前 100 名到底是什么样的人?
- MD5Util、SHA1Util、HmacMD5Util、HmacSHAUtil(未测试)
- Spark Transformation —— glom
- 获取启动图片
- Haproxy 配置项\配置实例
- 分治法专题
- apache commons fileupload 安全漏洞(2016-07-01更新)
- LeetCode之复制有random指针的链表Copy List with Random Pointer
- java图片压缩 (未测试)
- gradle 神器编译不同的渠道包
- 非IE内核浏览器支持activex插件