单片机一个程序中断带循环的问题,谢谢啦!

#include<reg52.h> //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义

/*------------------------------------------------
花样表格
------------------------------------------------*/
unsigned char code seg[]={0xe7,0xdb,0xbd,0x7e,
0xbd,0xdb,0xe7,0x0f,
0xf0,0x00,0xff
};//rom允许情况可以无限添加
unsigned char num=0,i;
unsigned char KeyPressFlag,temp;//定义按键标志位
void delayms(unsigned int xms);
void Init_INT0(void); //外部中断0初始化和
void keyscan(void);
/*------------------------------------------------
主函数
------------------------------------------------*/
void Timer0_isr(void) interrupt 1
{
TH0=(65536-45872)/256;
TH1=(65536-45872)%256;
num++;

}
main()
{
unsigned char i; //定义一个无符号字符型
//局部变量 i 取值范围 0~255

TMOD=0x01;
TH0=(65536-45872)/256;
TH1=(65536-45872)%256;
EA=1;
ET0=1;
TR0=1;
Init_INT0();
while(1)
{
if(num==20)
{
num=0;
P0=seg[i];
if(i==11)
{
i=0;
}
i++;
}

if(KeyPressFlag==1)
{
KeyPressFlag=0;
keyscan();
}
}

}

void keyscan(void)
{

ET0=0;
TR0=0;
P0=0x55;
delayms(5000);
ET0=1;
TR0=1;

}
void delayms(unsigned int xms)
{unsigned int x,j;
for(x=xms;x>0;x--)
for(j=110;j>0;j--);
}
void Init_INT0(void)
{
EA=1; //全局中断开
EX0=1; //外部中断0开
IT0=1; //边沿触发
}
void ISR_INT0(void) interrupt 0
{
KeyPressFlag=1; //表明按键有动作,可以进行按键扫描

}
这是代码,在第一次循环的时候花样灯是正常的,第二次循环开始后每次循环的第一个灯都是错的,不知道为什么?求帮忙看看,哪里有问题,我这里面的中断0用一个独立按键接的P3.2,如果我有是个输入怎么办呀?四个输入是相与的,就是任意一个键按下,都会导致循环的发生,想不通,教教我吧,谢谢啦

第1个回答  2014-02-11
#include<reg52.h>

unsigned char code seg[] = {
0xe7,0xdb,0xbd,0x7e,0xbd,0xdb,
0xe7,0x0f,0xf0,0x00,0xff};

unsigned char num = 0, i = 0, KeyPressFlag = 0;

void delayms(unsigned int xms)
{
unsigned int x, j;
for(x=xms;x>0;x--) for(j=110;j>0;j--);
}

void keyscan(void)
{
TR0 = 0;
P0 = 0x55;
delayms(5000);
P0 = seg[i]; //恢复原来的显示内容
TR0 = 1;
}

main()
{
TMOD = 0x01;
TH0 = (65536 - 45872) / 256;
TL0 = (65536 - 45872) % 256; //不是TH1
TR0 = 1;
ET0 = 1;
EX0 = 1;
IT0 = 1;
EA = 1;

while(1) {
if(num >= 20) {
num = 0;
P0 = seg[i];
i++;
if(i == 11) i = 0;
}
if(KeyPressFlag) {
KeyPressFlag = 0;
keyscan();
}
}
}
void ISR_INT0(void) interrupt 0
{
KeyPressFlag = 1;
}
void Timer0_isr(void) interrupt 1
{
TH0 = (65536 - 45872) / 256;
TL0 = (65536 - 45872) % 256; //不是TH1
num++;
}

已经可以了。追问

您说的3个地方我都改了,可是还是原来那样呀?不过我很纳闷呀?为什么我原来定时器部分写错了,但是这一部分运行的时候没有出错呢?

追答

您说的3个地方我都改了,可是还是原来那样呀?
--难道,第一个灯还是错的?

不过我很纳闷呀?为什么我原来定时器部分写错了,但是这一部分运行的时候没有出错呢?

--TL0 = (65536 - 45872) % 256; //不是TH1

--你的 TL0,没有重新赋值,那么,它就是零。
--这时,照样可以定时,但是,定时的时间,就不准确了。

追问

第一个灯还是错的,不过刚刚二楼解决了,我在循环的时候把第一个灯给漏掉了,第二个我也懂了,定时间不准了,就是还是那个问题,我这里面的中断0用一个独立按键接的P3.2,如果我有4个输入怎么办呀?四个输入是相与的,就是任意一个键按下,都会导致外部中断0的发生,想不通,教教我吧,谢谢啦,上次你给的是汇编的,看不懂看,没怎么学那东西,来点c语言的吧,

追答

第一个灯还是错的,
--不可能的。

--你不要改你的程序,你直接执行我的程序,就好了。
--我写的程序,有下面的部分:
i++;
if(i == 11) i = 0;
--那么,第一个灯,就不会错的。

如果我有4个输入怎么办呀?四个输入是相与的,...

--不光要相与,还要把四个输入,同时送到单片机的四个引脚。
--进入中断后,根据四个引脚,执行不同的程序,即可。

追问

你那个I++改了没标注一下,其他的都标注了,我就没看见那个了,不好意思了,最后那个问题,貌似是懂了,就是怎么把4个输入相与,我还不会呢,怎么实现多个输入我倒是有点会了。

追答

抢答器,有八个选手。

与门。

任意一个选手按下键,都会引起外部中断。

http://hi.baidu.com/do_sermon/item/ae2e0656175672c8d2e10c27

第2个回答  2014-02-11
这样改比较好理解:这几行:
if(i==11)
{
i=0;
}
i++;
将i++;移到前面,改成这样
i++;
if(i==11)
{
i=0;
}
i 先加1,再判断等于11,否则先判后加1,i 就不会有0了。追问

还是你比较厉害,这么小的地方都能发现,我还有个问题您还没回答呢,我这里面的中断0用一个独立按键接的P3.2,如果我有4个输入怎么办呀?四个输入是相与的,就是任意一个键按下,都会导致外部中断0的发生,想不通,教教我吧,谢谢啦

追答

就是任意一个键按下,都会导致外部中断0的发生。

很简单了,见下图。因为现在的中断程序只有一个,所以,还不用区别是按哪键。如果需要的话,这四个键就不能这么接了。

追问

这个电路我会,就是在单片机上怎么实现这四个键的相与我不会。

追答

这就能在单片机上实现这四个键的相与,符合你的要求:
“就是任意一个键按下,都会导致外部中断0的发生。”
你到底想要什么呀?

追问

电路是这样的,但是单片机上你怎么连在一起呢?四个按键是独立的,你打算通过什么器件实现他的相与,

追答

早说呀,因为那么接可以符合你的要求,就没有考虑其他了。这也很简单的。下图,用一个四输入的与门就行了。

本回答被提问者采纳
第3个回答  2014-02-10
//你这个程序i除了第一次外,以后都不会有0这个值。修改如下。
while(1)
 {
     if(num==20)
{
num=0;
P0=seg[i];
        i++;
        i%=11;
 }

追问

对的,谢谢了。

第4个回答  2014-02-10
第二次循环之前没有清零追问

额,好像不是这个问题,二楼帮忙解决了,但还是谢谢你的回答。

追答

我现在不知道你原理图怎么样的,你大致的工作原理怎么样?你先把if i=11改成10

相似回答