OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 2356|回复: 3

外部中断抢占优先级的问题

[复制链接]

9

主题

25

帖子

0

精华

初级会员

Rank: 2

积分
96
金钱
96
注册时间
2014-2-21
在线时间
12 小时
发表于 2019-8-30 14:21:36 | 显示全部楼层 |阅读模式
1金钱
今天学习外部中断的时候,写了一段程序,想验证一下高抢占优先级如何打断低抢占优先级。代码如下
void MY_EXTI_Init(void)
{
        EXTI_InitTypeDef EXTI_InitStructure;
        NVIC_InitTypeDef NVIC_InitStructure;
       
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
        GPIO_EXTILineConfig(GPIO_PortSourceGPIOE, 2);
        GPIO_EXTILineConfig(GPIO_PortSourceGPIOE, 3);
        GPIO_EXTILineConfig(GPIO_PortSourceGPIOE, 4);
       
        EXTI_InitStructure.EXTI_Line=EXTI_Line2;
        EXTI_InitStructure.EXTI_Mode=EXTI_Mode_Interrupt;
        EXTI_InitStructure.EXTI_Trigger=EXTI_Trigger_Falling;
        EXTI_InitStructure.EXTI_LineCmd=ENABLE;
        EXTI_Init(&EXTI_InitStructure);
       
        EXTI_InitStructure.EXTI_Line=EXTI_Line3;
        EXTI_Init(&EXTI_InitStructure);
       
        EXTI_InitStructure.EXTI_Line=EXTI_Line4;
        EXTI_Init(&EXTI_InitStructure);
       
        NVIC_InitStructure.NVIC_IRQChannel=EXTI2_IRQn;
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2;
        NVIC_InitStructure.NVIC_IRQChannelSubPriority=2;
        NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
        NVIC_Init(&NVIC_InitStructure);
       
        NVIC_InitStructure.NVIC_IRQChannel=EXTI3_IRQn;
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1;
        NVIC_InitStructure.NVIC_IRQChannelSubPriority=2;
        NVIC_Init(&NVIC_InitStructure);
       
        NVIC_InitStructure.NVIC_IRQChannel=EXTI4_IRQn;
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1;
        NVIC_InitStructure.NVIC_IRQChannelSubPriority=1;
        NVIC_Init(&NVIC_InitStructure);
       
}

void EXTI2_IRQHandler(void)
{
        LED0=!LED0;
        delay_ms(50000);
        LED0=!LED0;                 
        EXTI_ClearITPendingBit(EXTI_Line2);  
        delay_ms(20);
}

void EXTI3_IRQHandler(void)
{                         
        LED1=!LED1;
        delay_ms(50000);
        LED1=!LED1;         
        EXTI_ClearITPendingBit(EXTI_Line3);  
        delay_ms(20);       
}

void EXTI4_IRQHandler(void)
{

        LED0=!LED0;
        LED1=!LED1;
        delay_ms(50000);
        LED0=!LED0;
        LED1=!LED1;                  
        EXTI_ClearITPendingBit(EXTI_Line4);  
        delay_ms(20);
}


中断线2的抢占优先级是2,响应优先级是2(key2)
中断线3的抢占优先级是1,响应优先级是2(key1)
中断线4的抢占优先级是1,响应优先级是1(key0)
那么4和3应该都能打断2

而实际现象是,按下key2后,LED0点亮,立即按下key1,LED1并没有立即点亮,而是LED0熄灭后再点亮。哪位大哥能给解释一下啊

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

8

主题

182

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
421
金钱
421
注册时间
2017-3-8
在线时间
114 小时
发表于 2019-8-30 14:58:42 | 显示全部楼层
把你的中断函数里的delay换成计数,然后再试试
回复

使用道具 举报

7

主题

175

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1327
金钱
1327
注册时间
2019-7-11
在线时间
165 小时
发表于 2019-8-30 17:11:52 | 显示全部楼层
本帖最后由 礼拜天真好 于 2019-8-30 17:21 编辑

在中断里面就不要用systick的延时了
0.png
1.png

整个中断系统还是比较麻烦的,虽然优先级可设置但是还是需要下很大功夫去研究手册才能保证你的设置能达到你想要的结果



世界和平
回复

使用道具 举报

1

主题

48

帖子

0

精华

初级会员

Rank: 2

积分
166
金钱
166
注册时间
2019-3-5
在线时间
42 小时
发表于 2019-8-30 20:48:30 | 显示全部楼层
15937417823 发表于 2019-8-30 14:58
把你的中断函数里的delay换成计数,然后再试试

1.我觉得还是换成while死循环的好,四个中断都设置成死循环。
2.然后滴答定时器的中断属于内核中断,查询cm3手册是可以看到其中断优先级寄存器的值的,一般来说,其优先级都比较低,是15。所以你的delayms函数根本就跑不了。
3.一般内核和内核之外的外设中断等级也是通过软件比较的,比如把group等级设置为2.
对于systick这个中断等级寄存器 名字我忘了,但是默认值是0X0F,也就是1111B,那么对应的优先级就是11B,子优先级就是11B,也是3,3。
就像楼上说的,不要用delay了在里面。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-10 04:02

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表