renwocai 发表于 2012-5-29 23:15:02

(结贴,仿真BUG)请教:用定时器作的动态数码管扫描总是.

本帖最后由 renwocai 于 2012-5-30 11:33 编辑

比如4位共阳数码管,我希望它显示0123,结果只显示012,段码接P0口,位码接P2.0到P2.3.
程序如下:#include <at89x52.h>
#define uchar unsigned char
uchar code tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
uchar i=0;
sbit h4=P2^3;        //共阳,低电平有效
sbit h3=P2^2;
sbit h2=P2^1;
sbit h1=P2^0;

void timer0()interrupt 1
{
        TH0=(65536-10000)/256;
        TL0=(65536-10000)%256;
        switch(i)
        {
                case 0:
                {
                        h1=1;h2=0;h3=0;h4=0;P0=tab;
                };break;
                case 1:
                {
                        h1=0;h2=1;h3=0;h4=0;P0=tab;
                };break;               
                case 2:
                {
                        h1=0;h2=0;h3=1;h4=0;P0=tab;
                };break;               
                case 3:
                {
                        h1=0;h2=0;h3=0;h4=1;P0=tab;
                };break;
        }
        i++;
        if(i==4)
        i=0;
}
main()
{
        TMOD=0X01;
        EA=1;
        ET0=1;
        TH0=(65536-50000)/256;
        TL0=(65536-50000)%256;
        TR0=1;
        while(1);
}结果如下:

lxa0 发表于 2012-5-29 23:23:55

硬件或者接线有问题~~~~~~~~

renwocai 发表于 2012-5-29 23:30:31

接线就是仿真图片上的。

eblc1388 发表于 2012-5-29 23:31:25

楼上我都服了你。

仿真上运行你还说"硬件或者接线有问题" ?{:titter:}

renwocai 发表于 2012-5-29 23:34:40

肯定是程序问题,但我想不出来程序哪儿有问题了。

提示,如果我在仿真中把晶振调到0.12MHZ,则可看到每一位轮流点亮,包括最后一位的3

zhanzhp001 发表于 2012-5-29 23:36:55

解决没有?

renwocai 发表于 2012-5-29 23:38:10

没有。应该是最后一位点亮时间过短。但不知道为什么

little_Monkey 发表于 2012-5-30 00:15:24

把case0~3依次换成case 1~4,然后自己想想为什么

little_Monkey 发表于 2012-5-30 00:27:19

renwocai 发表于 2012-5-29 23:38 static/image/common/back.gif
没有。应该是最后一位点亮时间过短。但不知道为什么

这个问题有多种方法可以解决,除了上面说明的外,还可以直接把if(i==4) i=0;放到switch前面,switch里面不用修改

millwood0 发表于 2012-5-30 01:00:40

check out the waveform on the pins. animation in proteus is subject to many limitations.

無智 发表于 2012-5-30 01:03:45

主要还是i++和i==4的问题。

elecfun 发表于 2012-5-30 01:09:35

#include <at89x52.h>
#define uchar unsigned char

uchar code tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
uchar i=0;

void timer0() interrupt 1
{
    TH0=(65536-10000)/256;
    TL0=(65536-10000)%256;
   
    P2 = 0x01 << i;
    P0 = tab[i];
    if(++i >= 4)
      i = 0;
}

void main(void)
{
    TMOD = 0x01;
    EA   = 1;
    ET0= 1;
    TH0= (65536-10000)/256;
    TL0= (65536-10000)%256;
    TR0= 1;

    while(1) ;
}

millwood0 发表于 2012-5-30 07:16:51

here is the waveform on the various pins.

As you can see, h4 did go high and the desired value (0xb0) is written on P0 when h4 went high.

what you observed is proteus' animation anomaly.

the lesson learned here is that simulation is only useful if you understand its limitations.

renwocai 发表于 2012-5-30 07:46:28

little_Monkey 发表于 2012-5-30 00:27 static/image/common/back.gif
这个问题有多种方法可以解决,除了上面说明的外,还可以直接把if(i==4) i=0;放到switch前面,switch里面 ...

这样改了之后是这个结果:

renwocai 发表于 2012-5-30 07:49:03

elecfun 发表于 2012-5-30 01:09 static/image/common/back.gif
#include
#define uchar unsigned char



这样写的确没有问题,我之前写八位的就是这么写的,但是如果四位直接这么写的话会影响到没有用到的其它P2口。而且,在逻辑上我的程序应该和这个是一样的啊

renwocai 发表于 2012-5-30 07:56:07

millwood0 发表于 2012-5-30 07:16 static/image/common/back.gif
here is the waveform on the various pins.

As you can see, h4 did go high and the desired value (0xb ...

实物和仿真看到的效果是一样的。

millwood0 发表于 2012-5-30 08:31:38

实物和仿真看到的效果是一样的。

that tells you a lot, doesn't it?

xiaobendan001 发表于 2012-5-30 10:58:39

本帖最后由 xiaobendan001 于 2012-5-30 11:00 编辑

程序好像没有问题啊,不过俺习惯CASE后面不用{}的。
刚用KEIL模拟了一下,很好啊,i=0放哪儿都可以了。

renwocai 发表于 2012-5-30 11:32:27

问题找到,正如millwood0所说,确定为仿真软件的BUG.现将程序和仿真打包上传。
事先我的实物因为接触不良,正好也是最后一位不亮,使我对这个程序产生了怀疑。仿真上的非门在实物上是三极管。

hefq 发表于 2012-5-30 13:15:07

uchar code tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
uchar i=0;
sbit h4=P2^3;      //共阳,低电平有效
sbit h3=P2^2;
sbit h2=P2^1;
sbit h1=P2^0;
disp()
{
        if(i==0){h4=0;P0=tab;h1=1;}
        if(i==1){h1=0;P0=tab;h2=1;}
        if(i==2){h2=0;P0=tab;h3=1;}
        if(i==3){h3=0;P0=tab;h4=1;}
        i++;
        if(i==4){i=0;}
}
main()
{
while(1)
{
        disp();
}
}改到中断外可以了,没必要放中断里面吧

millwood0 发表于 2012-5-30 18:43:30

确定为仿真软件的BUG.

it is not a bug. it is your inability to understand its limitations.
页: [1]
查看完整版本: (结贴,仿真BUG)请教:用定时器作的动态数码管扫描总是.