在线时间721 小时
UID3469866
注册时间2018-4-19
NXP金币3946

TA的每日心情 | 慵懒 2025-5-7 08:45 |
---|
签到天数: 279 天 连续签到: 1 天 [LV.8]以坛为家I
版主
  
- 积分
- 11199

- 最后登录
- 2025-9-9
|
其实RT1052的中断优先级的配置方式和其他M系列的单片机配置方式基本一样,需要注意的是,RT1052只支持16位优先级,[7:4]
这次我们使用的主要是下面两个函数(看到NVIC_EnableIRQ没有,其实我们用的EnableIRQ就是调用了它(可见fsl_common.h第355—393行))
先看一下NVIC_SetPriorityGrouping函数内部
__STATIC_INLINE void __NVIC_SetPriorityGrouping(uint32_t PriorityGroup)
{
uint32_t reg_value;
uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */
reg_value = SCB->AIRCR; /* read old register configuration */
reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */
reg_value = (reg_value |
((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) |
(PriorityGroupTmp << 8U) ); /* Insert write key and priorty group */
SCB->AIRCR = reg_value;
}
可以看到函数主要是对AIRCR的8—10位进行配置的
这里是用来配置优先级分组的,让我们去看4—19页
4—19是有关分组的说明,这里RT1052只有[7:4]有效,所以我们可以定义的有3 [16.1],4 [8.2],5 [4.4],6 [2.8],7 [1.16]这几种
然后是NVIC_SetPriority函数(这次只分析普通中断)
__STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
{
if ((int32_t)(IRQn) >= 0)
{
NVIC->IP[((uint32_t)(int32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL);
}
else
{
SCB->SHPR[(((uint32_t)(int32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL);
}
}
可以看出,每个中断都有一个8位的字节去对应,一共256个中断优先级(实际需分为抢断位和响应位)
要注意__NVIC_PRIO_BITS,这里
#define __NVIC_PRIO_BITS 4 /**< Number of priority bits implemented in the NVIC */
已被定义为4,也就是我们在定义优先级的时候一共有0—15这几个参数可以选择
上程序
- #include "fsl_device_registers.h"
- #include "fsl_debug_console.h"
- #include "board.h"
- #include "pin_mux.h"
- #include "clock_config.h"
- #include "fsl_lpuart.h"
- #include "fsl_gpt.h"
- #include "delay.h"
- #define DISPLAY_CLK(name) (PRINTF("%s:%d\r\n",#name,CLOCK_GetFreq(name))) //打印对应时钟
- int main(void)
- {
- gpt_config_t gptConfig;
- NVIC_SetPriorityGrouping(((uint32_t)0x3)); //设置中断优先级分注,4:0,全为抢断优先级
- NVIC_SetPriority(GPT1_IRQn,0); //设置中断优先级
- NVIC_SetPriority(GPT2_IRQn,1);
-
- BOARD_ConfigMPU();
- BOARD_InitPins();
- BOARD_BootClockRUN();
- BOARD_InitDebugConsole();
- DISPLAY_CLK(kCLOCK_IpgClk);
- DISPLAY_CLK(kCLOCK_OscClk);
-
- gptConfig.clockSource = kGPT_ClockSource_Osc; //选择时钟源为 OSC
- gptConfig.divider = 1U; //设置时钟分频
-
- GPT_Init(GPT1, &gptConfig); //初始化
- GPT_SetOutputCompareValue(GPT1, kGPT_OutputCompare_Channel1, CLOCK_GetFreq(kCLOCK_OscClk)); //设置输出比较通道的比较值
- GPT_EnableInterrupts(GPT1, kGPT_OutputCompare1InterruptEnable); //使能对应中断
- EnableIRQ(GPT1_IRQn); //使能中断
-
- GPT_Init(GPT2, &gptConfig); //初始化
- GPT_SetOutputCompareValue(GPT2, kGPT_OutputCompare_Channel1, CLOCK_GetFreq(kCLOCK_OscClk)); //设置输出比较通道的比较值
- GPT_EnableInterrupts(GPT2, kGPT_OutputCompare1InterruptEnable); //使能对应中断
- EnableIRQ(GPT2_IRQn); //使能中断
-
- GPT_StartTimer(GPT1); //开始计时
- GPT_StartTimer(GPT2); //开始计时
-
- while (1)
- {
- }
-
- }
- void GPT1_IRQHandler(void)
- {
- GPT_ClearStatusFlags(GPT1, kGPT_OutputCompare1Flag); //清除中断标志位
- LPUART_WriteBlocking(LPUART1, "1\r\n",3);//阻塞方式发送一串字符
- __DSB();
- }
- void GPT2_IRQHandler(void)
- {
- GPT_ClearStatusFlags(GPT2, kGPT_OutputCompare1Flag); //清除中断标志位
- LPUART_WriteBlocking(LPUART1, "2\r\n",3);//阻塞方式发送一串字符
- GPT_StopTimer(GPT2); //关闭计数
- while(1){}
- __DSB();
- }
复制代码
可以看到定义了两个GPT中断(有关GPT的使用方式可见飞凌RT1052——8.GPT定时器定时https://www.nxpic.org.cn/module/foru ... 258&fromuid=3469866(出处: 恩智浦技术社区)),GPT1是普通的(打印1)。GPT2一旦进入就会把程序卡在这里(打印2)(这种写法很危险,只是实验用)。
然后配置分组模式为3也就是[16.1],全是抢断优先级。配置GPT1中断优先级为0(数越低优先级越高),GPT2优先级为1(此处都是抢断优先级)
实验效果
可以看到,还在一直输出1,说明GPT1的中断会打断GPT2的中断。接下来我们交换GPT1和GPT2的优先级
NVIC_SetPriority(GPT1_IRQn,1); //设置中断优先级
NVIC_SetPriority(GPT2_IRQn,0);
实验效果
可见,GPT1的中断无法打断GPT2的中断了
最后附上工程
MDK版本:5.22
pack:NXP.MIMXRT1052_DFP.10.0.1.pack
下载算法:飞凌嵌入式提供的 MIMXRT_QSPIFLASH.FLM
启动方式:spi flash启动
下载方式:STlink
9.nvic.zip
(1.46 MB, 下载次数: 23)
|
|