一、准备工作
1、KEIL C51编译环境
2、外部中断EINT示例代码-MC96F6332D
3、MC96F6332D 开发板
4、USB-OCD II仿真器
二、代码部分
1、现代单片机MC96F6332D提供了内部中断优先级设置的寄存器IP1和IP;如下图所示:
注意:默认的优先级为上图蓝色框图中所示,优先级呈“之”字形逐渐下降,其中Interrupt0/6//12/18为一组,Interrupt1/7/13/19为一组,以此类推,共计6组;其中最多可以设置4组的优先级,剩余的2组按照上图默认方式再进行排序。
2、在中断的方框图中也可以看出,有4级优先级可以进行配置:
3、根据MC96F6332D外部中断EINT的示例代码,此示例在外部中断的工程上进行修改。工程代码中采用了外部中断0和8两个外部中断,具体如下所示:
外部中断 | 引脚号 | 端口号 | 中断向量号 Interrupt |
EINT0 | 29 | P02 | 5 |
EINT8 | 4 | P52 | 6 |
4、在中断优先级默认的情况下,外部中断EINT8(Interrupt6)优先级高于外部中断EINT0(Interrupt5);所以EINT0(Interrupt5)的中断函数会被EINT8(Interrupt6)中断;故增加延时函数并修改中断服务函数,增加低优先级EINT0(Interrupt5)中断函数的执行时间;代码如下所示:
//延时函数
void delay_time(unsigned int tt)
{
unsigned int times;
while(tt--)
{
times = 1000;
while(times--);
}
}
//中断函数修改如下
//======================================================
// interrupt routines
//======================================================
void INT_Ext8() interrupt 6
{
// External interrupt 8
sei();
EXIT8_STA = 1; //外部中断8标志使能
printf("EXIT 8 Interrupt into.\r\n");
delay_time(3267);
a_break++;
if(a_break >= 200)
a_break = 0;
printf("EXIT 8 Interrupt out.\r\n");
}
void INT_Ext0_7() interrupt 5
{
// External interrupt 0 ~ 7
//判断外部引脚0是否被按下
sei();
printf("EXIT 0 Interrupt into .\r\n");
if(EIFLAG0 & 0x01)
{
EIFLAG0 &= 0xFE;
EXIT0_STA = 1; //外部中断0标志使能
}
// delay_time(3267);
// a_break++;
// if(a_break >= 200)
// a_break = 0;
printf("EXIT 0 Interrupt out.\r\n");
}
5、工程代码编译时会提示有2个警告,是因为中断函数中调用了printf函数,此处忽略警告。把代码下载到MC96F6332D并进行仿真,红色方框中分别为两个中断函数的执行时间;
从仿真结果上可以看到EINT0(Interrupt5)的中断函数并没有被EINT8(Interrupt6)中断,这个是为什么???
6、尝试修改中断优先级寄存器的值,将Interrupt 6所在的这一组强制定义为最高优先级(按照“之”字形的优先级顺序,其实还是保持默认的高优先级);在Main函数最前端增加如下代码:
//重新定义优先级
IP1 = 0x01;
IP = 0x01;
7、将代码进行编译并下载;再进行程序的仿真,其代码仿真结果如下所示:
外部的EINT8(Interrupt6)成功将EINT0(Interrupt5)进行中断;程序运行结果符合预期设置;所以中断嵌套必须先进行优先级分组。
注意:在需要被中断的中断函数中必须增加sei();函数,否则程序的嵌套将得不到正确运行,在多级中断章节中有说明:(我也是踩坑爬过来的)
8、试想一下:高优先级可以打断低优先级的中断,那么高优先级的中断执行时,如果低优先级中断到来,这个时候低优先级的中断是否会被MCU丢弃?
答案:高优先级中断执行过程中,低优先级中断肯定不会中断高优先级的中断函数,但是低优先级的中断会在高优先级中断执行完毕后被响应;
如果低优先级中断在高优先级中断执行的过程到来了多次,最后也是仅仅保留一次的响应机会。大家可以自行验证,在原来程序上简单修改即可,下面直接上结果供大家参考:
三、实验总结:
1、中断函数在保持默认优先级的情况下不会进入中断嵌套,中断函数是根据中断顺序一个接一个的执行;如果高优先级的中断在执行过程中,低优先级的中断到来,高优先级中断函数执行完毕后,低优先级的中断将会被执行;
2、在中断嵌套的使用中:被中断的函数中需要增加sei();函数,否则不能进入中断的嵌套;
3、使用中断的嵌套必须先进行中断组优先级的配置(在中断组中,中断优先级的响应顺序不能被改变;例如中断组Interrupt0/6//12/18中0-->6-->12-->18的优先级顺序不能被改变);
4、具体的代码可以访问链接:https://share.weiyun.com/5E7eyoX;进行免费下载。
因为小编自己能力水平有限,文中难免有错误或表达失误的信息,还望广大阅读者留言批评指正,谢谢。