标题: 51单片机外部中断0问题 [打印本页]

作者: tzwanjing    时间: 2015-1-19 20:56
标题: 51单片机外部中断0问题
本来主程序时让数码管1 3 5 7亮1s 然后全部数码管熄灭0.5s 做循环,每次循环按照数组里设置的字符变化(n n 5 2 0 1 3 1 4)。
外部中断0是让第一个LED亮。

模拟调试结果:
把P3^2(INT0)拉低(接地),即执行中断程序时,约1-2s 后,首先数码管1 3 5 7 会从之前的显示变为显示'8',然后持续1-2s,最后只剩第8个数码管显示'8',其余的数码管都熄灭。
取消P3^2接地(结束中断),主程序有时正常,有时在第8个数码管跑一个循环后正常。

从试验板的运行结果看,好像是在执行中断程序的时候使得段锁存器和位锁存器的值有所变化。请大虾帮忙找下问题在哪里。

程序代码:


#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
sbit lodu=P2^6;
sbit lowi=P2^7;
sbit q1=P1^4;
uint a;
uchar code table[]={0x37,0x37,0x6d,0x5b,0x3f,0x06,0x4f,0x06,0x66};
void delay(uint);
void main()
{        
        while(1)
        {               
                EA=1;//开总中断
                EX0=1;//开外部中断0
               
                        
                for(a=0;a<9;a++)
                {
                        q1=1;//LED 电源打开

                        lowi=1;//位锁存器直通
                        P0=0xaa;//给位锁存器赋值(片选1 3 5 7 数码管)
                        lowi=0;//位锁存器锁存

                        lodu=1;//段锁存器直通
                        P0=table[a];//给段锁存器赋值,
                        lodu=0;//段锁存器锁存
                        delay(380);//延时1s

                        lodu=1;//段锁存器直通
                        P0=0x00;//给段锁存器赋值
                        lodu=0;//段锁存器锁存
                        delay(170);//延时0.5s
        
                };
        }

}



void delay(uint z)//延时程序
{
        uint x,y;
        for(x=z;x>0;x--)
        {
                for(y=200;y>0;y--)
                {
                };

        };


}


void exter0()interrupt 0//中断子程序
{
        q1=0;
        P0=0x7f;
        
        

}


作者: dgahz    时间: 2015-1-19 21:43
没上板试验,试试这样行不行:
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
sbit lodu=P2^6;
sbit lowi=P2^7;
sbit q1=P1^4;
uint a;
uchar code table[]={0x37,0x37,0x6d,0x5b,0x3f,0x06,0x4f,0x06,0x66};
void delay(uint);
void main()
{            EA=1;//开总中断
        EX0=1;//开外部中断0
        IT0=1;
        while(1)
        {               
               
               
                        
                for(a=0;a<9;a++)
                {
                        q1=1;//LED 电源打开

                        lowi=1;//位锁存器直通
                        P0=0xaa;//给位锁存器赋值(片选1 3 5 7 数码管)
                        lowi=0;//位锁存器锁存

                        lodu=1;//段锁存器直通
                        P0=table[a];//给段锁存器赋值,
                        lodu=0;//段锁存器锁存
                        delay(380);//延时1s

                        lodu=1;//段锁存器直通
                        P0=0x00;//给段锁存器赋值
                        lodu=0;//段锁存器锁存
                        delay(170);//延时0.5s
        
                };
        }

}



void delay(uint z)//延时程序
{
        uint x,y;
        for(x=z;x>0;x--)
        {
                for(y=200;y>0;y--)
                {
                };

        };


}


void exter0()interrupt 0//中断子程序
{
        q1=0;
      
        
        

}

作者: tzwanjing    时间: 2015-1-20 09:20
你用的IT=1(下降沿出发中断),且中断程序时让全部8个led亮,上板试验效果是P3^2接地,8个led闪烁一下。程序没有问题。

但是我想问的是用IT0=0 (低电平出发中断),为何P3^2接地,且接地没有断开的过程中,数码管的显示还是会变化。

依照你的建议 我把程序稍稍该了一点
想要的试验结果是:
P3^2一直接地的过程中主程序停止在断点前的一步不动,一直执行中断程序(8个led全亮),当断开P3^2的接地,跳出中断(8个led熄灭,继续执行主程序)


程序

#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
sbit lodu=P2^6;
sbit lowi=P2^7;
sbit q1=P1^4;
uint a;
uchar code table[]={0x37,0x37,0x6d,0x5b,0x3f,0x06,0x4f,0x06,0x66};
void delay(uint);
void main()
{       

        EA=1;
        EX0=1;
        IT0=0;
        while(1)
        {
       

               
                //EA=1;//开总中断
                //EX0=1;//开外部中断0
               
                       
                for(a=0;a<9;a++)
                {
                        q1=1;//LED 电源关闭

                        lowi=1;//位锁存器直通
                        P0=0xaa;//给位锁存器赋值(片选1 3 5 7 数码管)
                        lowi=0;//位锁存器锁存

                        lodu=1;//段锁存器直通
                        P0=table[a];//给段锁存器赋值,
                        lodu=0;//段锁存器锁存
                        delay(380);//延时1s

                        lodu=1;//段锁存器直通
                        P0=0x00;//给段锁存器赋值
                        lodu=0;//段锁存器锁存
                        delay(170);//延时0.5s
       
                };
        }

}



void delay(uint z)//延时程序
{
        uint x,y;
        for(x=z;x>0;x--)
        {
                for(y=200;y>0;y--)
                {
                };

        };


}


void exter0()interrupt 0//中断子程序
{
        q1=0;
        //P0=0x7f;
       
       

}

试验结果: P3^2 接地8个led无序变化,数码管1 3 5 7 继续执行主程序,只是延时时间变长了
作者: dgahz    时间: 2015-1-20 11:35
再试试:
sbit P3.2=P3^2;
void exter0()interrupt 0//中断子程序
{      EA=0;
        q1=0;
        //P0=0x7f;
       while(P3.2==0);
        EA=1;

}
作者: dgahz    时间: 2015-1-20 11:55
用低电平触发中断
作者: tzwanjing    时间: 2015-1-20 13:54
OK问题解决了,另外 sbit P3.2=P3^2; 有错误,改为 sbit p32=P3^2;


没想明白为何要再中断程序中加
EA=0;
while(P3.2==0);
        EA=1;
意思就是只有在INT0脚在低电平时开总中断,否则关闭总中断。
总中断一直开着会对锁存器有影响吗?
作者: dgahz    时间: 2015-1-20 14:23
本帖最后由 dgahz 于 2015-1-20 14:31 编辑

进入中断服务程序后关中断使能,以便检测3.2脚电平状态,如是低电平,则程序不往下执行,停留在while这一句,否则往下执行,恢复中断使能,退出服务程序,跳回主程序断点继续循环。
作者: dgahz    时间: 2015-1-20 14:27
如果不这样处理,则程序将会在中断服务程序和主程序来回跳转,使得主程序断断续续缓慢执行。




欢迎光临 (http://www.51hei.com/bbs/) Powered by Discuz! X3.1