|
前面的帖子讲过,中断中所谓的打断优先级,是指的一件中断发生后,CPU可以打断正在执行的低级别的中断,立即转而执行这个刚发生的中断。 我们的这个实验的目的,一是观察正在执行的低级别的中断被一个高级别的中断打断它的执行,另一个,是证实对于STC来说高标号的中断就是高级别的中断,第三个,是当高级别的中断执行完成后,是否转回去执行先前被打断的中断。 我们的这个实验,在设计时,必须注意的是,那个计划被打断的中断,一定是正在执行中,而不能是可能出现计划被打断的中断在退出间隙发生了另一个高级别的中断。 这个实验中,所采用的中断源为两个,一个是定时器T0,打断级别设定为3;一个是定时器T1,打断级别设定为1。 程序运行过程是这样的:程序开始时,T1的是运行LED电位反转中断程序以驱动LED闪烁,当然每次电位反转都是一次T1的中断函数进出。待闪烁20次后,用while(1)让T1停在中断函数中即不再退出,并让LED保持在亮状态,这样T1就一直在中断的程序中运行。 程序开始时,T0也在运行中也在不断进出它的中断,但在自身中断次数小于200时并不对LED作任何控制,而一旦中断次数达到200次,则控制LED状态为灭,并用while(1)让T0停在其中断函数中不再退出。 所以,程序运行时,我们会看到LED先闪烁20次,然后就处于长亮状态,然后再过一段时间,我们会看到LED就灭了并一直处于灭的状态。 实验中,我们可以把T0和T1换一个位置,看看结果怎样。 程序很简单: #include "stc8h.h" #define LED P54 void LED_init(void) { P5M0&=~(1<<4);P5M1&=~(1<<4); } void TIM0_init(void) //T0初始化 { TMOD&=~(1<<3);//定时器功能 TMOD&=~(3<<0);//16位自动重装模式 AUXR&=~(1<<7);//对时钟作12分频作为定时器的工作频率 TL0=0xB0; TH0=0x3C; IP|=(1<<1);IPH|=(1<<1);//优先级3 ET0=1;//允许定时器溢出中断 TR0=1;//启动定时器 } void TIM1_init(void) //T1初始化 { TMOD&=~(1<<6);//定时器功能 TMOD&=~(3<<4);//16位自动重装模式 AUXR&=~(1<<6);//对时钟作12分频作为定时器的工作频率 TL1=0xB0; TH1=0x3C; IP|=(1<<3);IPH&=~(1<<3);//优先级1 ET1=1;//允许定时器溢出中断 TR1=1;//启动定时器 } void main() { LED_init(); LED=0; TIM0_init(); TIM1_init(); EA =1; //开总中断 while(1); } void tm1() interrupt 3 //这个的优先级是1 { unsigned char num; num++; LED=~LED; if(num==40) //闪烁20次之后 { num=0; LED=1; while(1); } } void tm0() interrupt 1 //这个的优先级是3 { unsigned char num; num++; if(num==200) { LED=0; while(1); } } 另外,我们也可以不用while(1)让程序一直停留在中断函数中,而是用延时程序替代而让其只在中断函数中停留一段时间后就退出,然后我们观察一下是个什么情况,这其中就包括高级别的T0退出后是否会让T1再次进出它的中断,也就是观察它是否会再次掌握对LED的控制权。 这部分我就不写了。 补充说明一下,尽管因为while(1)而让程序停留在中断函数中不出来了,但定时器仍然在嘀嘀嗒嗒地反复计时反复产生中断,但CPU是不再响应那些中断包括T0、T1自己产生的中断,除非又有一个更高级别的中断发生了。不过嘛,对于STC 来说标号3已经是最高级别的中断了。 以上有没有问题?恳请指正。
|