修改NVIC表优先级
修改NVIC表优先级
嘿,这个问题我太熟悉了!首先得纠正个小误区:咱们不用直接修改所谓的“NVIC表”(也就是中断向量表),中断优先级是通过NVIC的优先级配置寄存器来设置的,和向量表本身没关系~要让SPI中断优先级高于ADC,按下面的步骤来就行:
核心逻辑
NVIC的优先级分为抢占优先级和子优先级(不同MCU的分组方式可能不同,比如STM32支持5种分组):
- 抢占优先级数值越小,优先级越高,高抢占优先级的中断可以打断低优先级的中断
- 子优先级只有在抢占优先级相同时才会决定中断响应顺序
所以关键就是给SPI设置比ADC更小的抢占优先级数值。
具体操作(以STM32为例,分标准库和HAL库两种情况)
1. 标准库实现
首先得先设置优先级分组(这个整个系统只需要调用一次),比如选分组2(2位抢占优先级 + 2位子优先级):
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
然后分别配置SPI和ADC的中断优先级:
NVIC_InitTypeDef NVIC_InitStruct; // 配置SPI中断:抢占优先级设为0(最高级别) NVIC_InitStruct.NVIC_IRQChannel = SPI1_IRQn; // 替换成你实际用的SPI通道,比如SPI2_IRQn NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0; // 子优先级随便设,不影响这里的优先级对比 NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStruct); // 配置ADC中断:抢占优先级设为1(比SPI低) NVIC_InitStruct.NVIC_IRQChannel = ADC1_IRQn; // 替换成你实际用的ADC通道 NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1; NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0; NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStruct);
2. HAL库实现
HAL库的代码更简洁,同样先设置优先级分组(一般在HAL_Init()里已经配置了,如果需要修改可以手动调),然后直接设置优先级:
// 设置SPI中断优先级:抢占优先级0,子优先级0 HAL_NVIC_SetPriority(SPI1_IRQn, 0, 0); HAL_NVIC_EnableIRQ(SPI1_IRQn); // 设置ADC中断优先级:抢占优先级1,子优先级0 HAL_NVIC_SetPriority(ADC1_IRQn, 1, 0); HAL_NVIC_EnableIRQ(ADC1_IRQn);
注意事项
- 优先级分组一旦设置就不要随意更改,整个系统要统一,否则会导致优先级逻辑混乱
- 如果你的MCU不是STM32,原理是一样的:找到对应中断的优先级配置寄存器,给SPI设置比ADC更高的优先级(数值更小)就行
备注:内容来源于stack exchange,提问作者Hari Kumari
相关产品推荐
相关产品推荐

