重工电子论坛

标题: STC单片机中断开关问题 [打印本页]

作者: 李维强-15级    时间: 2015-7-31 23:47
标题: STC单片机中断开关问题
本帖最后由 李维强-15级 于 2015-8-1 00:55 编辑

单片机型号(STC12C2052AD, STC11F系列)
问题描述:单片机外部中断设置为下降沿触发,在单片机关闭外部中断使能期间,如果有下降沿到来,那么在单片机开启外部中断的时候,同样会响应外部中断。换句话说,单片机即使关闭外部中断,但是出现下降沿的时候,同样会被挂起。

下面做了个小实验:

               实验过程:
                        利用定时器,每过5秒开一次打开外部中断使能,再过5秒后关闭外部中断使能,如此反复。在打开外部中断使能的时候让LED3点亮,关闭外部中断使能的时候让LED3熄灭。
                        在关闭外部中断使能期间(LED3熄灭时),人为的让外部中断使能引脚“INT1”接地,使得产生下降沿中断。
              实验结果:
                        由于在中断使能关闭时(LED3熄灭的时候)INT1接收到下降沿中断,中断同样被挂起,以至于在重新打开中断使能的时候马上就进入中断。

以下是程序代码:

其中LED1,LED2是另外两个灯,进入外部中断函数后会依次把自己的状态取反一次


[C] syntaxhighlighter_viewsource syntaxhighlighter_copycode
#include<STC12C20XX.H>

sbit  led1=P1^5;
sbit  led2=P1^3;
sbit  led3=P1^2;
unsigned char count=0;
unsigned char INT_tag=0;
int count_T0 = 0;                        //记录T0的中断次数

void main(void)
{
        
        EA=1;                        //开启总中断
        IT1=1;                //设置INT1下降沿中断
        EX1=0;                //关闭INT1外部中断
        led3=0;                //让LED3先亮
        
        //以下是定时器操作
        ET0 = 1;                        //开定时器0中断
        //设置定时器0为50ms延时
        AUXR &= 0x7F;                //定时器始终12T分频模式
        TMOD &= 0xF0;                //设置定时器模式
        TMOD |= 0x01;                //设置定时器模式
        TL0 = 0x00;                //设置定时器初值
        TH0 = 0x4C;                //设置定时器初值
        TF0 = 0;                //清楚TF0标志
        TR0 = 1;                //定时器0开始计时
        
        while(1)
        {
        }
        
}


void T0_interrupt(void) interrupt 1
{
        TF0 = 0;                //清楚TF0标志

        //重装50mS的延时
        TL0 = 0x00;                //设置定时初值
        TH0 = 0x4C;                //设置定时初值
        
        if(++count_T0 == 100)                //==100表明延迟了5秒
        {
                count_T0 = 0;
               
                if(INT_tag==0)
                {
                        INT_tag=1;
                        led3=0;                                //点亮LED3
                        EX1=1;                //开启INT1外部中断
                }
                else
                {
                        INT_tag=0;
                        led3=1;                        //熄灭LED3
                        EX1=0;                //关闭INT1外部中断
                }
               
        }
        
}


void INT1_interrupt(void) interrupt 2
{
        if(count==0)
        {
                led1=~led1;
                count++;
        }
        else
        {
                if(count==1)
                {
                        led2=~led2;
                        count++;
                }
        }
        
        if(count>1)
                count=0;
        
        IE1 =0;                        //中断在最后清0,这个很重要,理论上是硬件自动清除,但是在中断执行的时间当中,有可能再次被挂起
        
}


以下是实验视频,最右边那个灯是LED3,注意,我分别2次在LED3灭的时候让INT1引出来的线接了下地,使得出现下降沿,结果却是中断同样被挂起。
[media=swf,500,375]%5Dhttp://www.tudou.com/v/IkIDU7Uutlg/&rpid=333327247&resourceId=333327247_04_05_99/v.swf[/media]





作者: 顾福源    时间: 2015-8-1 21:05
没看懂
作者: 胡小均    时间: 2016-1-3 20:03
应该是中断使用之前要软件清除中断标志吧!
作者: 李维强-15级    时间: 2016-1-5 00:27
胡小均 发表于 2016-1-3 20:03
应该是中断使用之前要软件清除中断标志吧!

对 问题是这样的




欢迎光临 重工电子论坛 (http://www.cqutlab.cn/) Powered by Discuz! X3.1