找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 8048|回复: 7
打印 上一主题 下一主题
收起左侧

51单片机外部中断0问题

[复制链接]
跳转到指定楼层
楼主
ID:47343 发表于 2015-1-19 20:56 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本来主程序时让数码管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;
        
        

}

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:67992 发表于 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;
      
        
        

}
回复

使用道具 举报

板凳
ID:47343 发表于 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 继续执行主程序,只是延时时间变长了
回复

使用道具 举报

地板
ID:67992 发表于 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;

}
回复

使用道具 举报

5#
ID:67992 发表于 2015-1-20 11:55 | 只看该作者
用低电平触发中断
回复

使用道具 举报

6#
ID:47343 发表于 2015-1-20 13:54 | 只看该作者
OK问题解决了,另外 sbit P3.2=P3^2; 有错误,改为 sbit p32=P3^2;


没想明白为何要再中断程序中加
EA=0;
while(P3.2==0);
        EA=1;
意思就是只有在INT0脚在低电平时开总中断,否则关闭总中断。
总中断一直开着会对锁存器有影响吗?
回复

使用道具 举报

7#
ID:67992 发表于 2015-1-20 14:23 来自手机 | 只看该作者
本帖最后由 dgahz 于 2015-1-20 14:31 编辑

进入中断服务程序后关中断使能,以便检测3.2脚电平状态,如是低电平,则程序不往下执行,停留在while这一句,否则往下执行,恢复中断使能,退出服务程序,跳回主程序断点继续循环。
回复

使用道具 举报

8#
ID:67992 发表于 2015-1-20 14:27 来自手机 | 只看该作者
如果不这样处理,则程序将会在中断服务程序和主程序来回跳转,使得主程序断断续续缓慢执行。
回复

使用道具 举报

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

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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