请高手进来,51单片机计时中断控制数码管的位选段选问题

时间:2022-02-03 09:49:55


/*程序功能,计时器,精确到0.1秒*/
#include<reg52.h>
#define UINT unsigned int
#define UCHAR unsigned char
sbit keyS2 = P3 ^ 4;
sbit dula = P2 ^ 6;
sbit wela = P2 ^ 7;
UINT time = 0;
UINT cnt = 0;
UCHAR code table[] = {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d,
                      0x07, 0x7f, 0x6f, 0x77, 0x7c, 0x37, 0x5e,
                      0x79, 0x71, 0x76, 0x38, 0x73, 0x3e, 0x80,
                      0x00}; 

void main()
{
    bit key();
    void display(UCHAR, UCHAR, UCHAR);
    UCHAR digits, tens, hundreds;
    TMOD = 0X01;
    EA = 1;
    ET0 = 1;
    TR0 = 1; 
    
    while(1)
    {
        if(key())
            TR0 = 0;
        else
            TR0 = 1;
        digits = time % 10;
        tens = time / 10 % 10;
        hundreds = time / 100;
        display(hundreds, tens, digits);      
    }   
}

bit key()
{
    void delay(UINT);
    if(keyS2 == 0)
    {
        delay(5);
        if(keyS2 == 0)
        {
            while(keyS2 == 0)
                ;  
            return 1;
        }
    }
    
    return 0;    
}

void display(UCHAR tube1, UCHAR tube2, UCHAR tube3)
{

    void delay(UINT);
    wela = 1;
    P0 = 0xfe;         //我的迷惑之处是display()函数和后面的display()函数的不同处。。
    wela = 0;
    dula = 1;
    P0 = table[tube1];
    dula = 0;
    delay(1);
    
    wela = 1;
    P0 = 0xfd;
    wela = 0;
    dula = 1;
    P0 = table[tube2];
    dula = 0;
    delay(1);
    
    wela = 1;
    P0 = 0xfb;
    wela = 0;
    dula = 1;
    P0 = table[tube3];
    dula = 0;
    delay(1);        
}

void timer1() interrupt 1
{
    TH0 = (65536 - 50000) / 256;
    TL0 = (65536 - 50000) % 256;
    if(++cnt == 2)
    {
        if(++time == 999)
            time = 0;
        cnt = 0;
    }
}

void delay(UINT ms)
{
    UINT x, y;

    for(x = ms; x; x--)
        for(y = 197; y; y--)
            ;
}


下面是另外一个display()函数

void display(UCHAR tube1, UCHAR tube2, UCHAR tube3)
{
    void delay(UINT);

      /*这个display()函数就是多了下面这三条语句,我不知道它们的用意
       *不是像上面那个display()函数那样就好吗?直接先送位选数,再送段选数据
       *为什么要再加多这三条语句
       *我用上面那个display()函数去编译,把.hex下载到实验板上运行,能正常运行
       *但在proteus上进行仿真时就不行了,显示不稳定,一闪一闪的。我总共要显示3个数码管
       *在proteus上仿真时有一两个还不会亮,但在实验板上就正常
       *用了这里的display()函数去编译,下载到实验板上正常运行,在proteus上也正常仿真
       *请高手指点下,一:这两个display()的区别在哪里
       *               二:为什么第一个display()函数在实验板上正常运行,仿真不行。
       *在这里先谢过了
         */
       
    wela = 1;       
    P0 = 0xff;
    wela = 0;
    dula = 1;
    P0 = table[tube1];
    dula = 0;
    wela = 1;
    P0 = 0xfe;
    wela = 0;
    
    delay(1);
    
    wela = 1;
    P0 = 0xff;
    wela = 0;
    dula = 1;
    P0 = table[tube2];
    dula = 0;
    wela = 1;
    P0 = 0xfd;
    wela = 0;
    
    delay(1);
    
    wela = 1;
    P0 = 0xff;
    wela = 0;
    dula = 1;
    P0 = table[tube3];
    dula = 0;
    wela = 1;
    P0 = 0xfb;
    wela = 0;
    
    delay(1);        
}


6 个解决方案

#1



/*我的迷或之处*/
wela = 1;       
    P0 = 0xff;
    wela = 0;
    dula = 1;
    P0 = table[tube1];
    dula = 0;
    wela = 1;
    P0 = 0xfe;
    wela = 0;
/*和下面的区别*/
wela = 1;
    P0 = 0xfe;
    wela = 0;
    dula = 1;
    P0 = table[tube1];
    dula = 0;

#2


好难搞吗,程序好难看啊,太长了,呵呵

#3


程序是新概念那本书上的,两个都没有问题,问题应该是protues软件自身的问题,对数码管的显示经常不正常,我试过很多

#4


多的那三条相当于初始化操作,初始的是相应地址的值
proteus里没有这三条语句的话 开始运行时它从软件映射的地址取值就很可能得到一个不确定的数 是由这个软件和运行环境决定的 应该叫数据堆栈吧。。。
而51的板子上没有变量储存功能 加不加那三条语句它都是 0xff

嗯,软件,仿了,不一定真。。

#5


引用 4 楼 rncjd 的回复:
多的那三条相当于初始化操作,初始的是相应地址的值
proteus里没有这三条语句的话 开始运行时它从软件映射的地址取值就很可能得到一个不确定的数 是由这个软件和运行环境决定的 应该叫数据堆栈吧。。。
而51的板子上没有变量储存功能 加不加那三条语句它都是 0xff

嗯,软件,仿了,不一定真。。


有理。。仿了不一定真

#6


引用 4 楼 rncjd 的回复:
多的那三条相当于初始化操作,初始的是相应地址的值
proteus里没有这三条语句的话 开始运行时它从软件映射的地址取值就很可能得到一个不确定的数 是由这个软件和运行环境决定的 应该叫数据堆栈吧。。。
而51的板子上没有变量储存功能 加不加那三条语句它都是 0xff

嗯,软件,仿了,不一定真。。

谢谢了。。

#1



/*我的迷或之处*/
wela = 1;       
    P0 = 0xff;
    wela = 0;
    dula = 1;
    P0 = table[tube1];
    dula = 0;
    wela = 1;
    P0 = 0xfe;
    wela = 0;
/*和下面的区别*/
wela = 1;
    P0 = 0xfe;
    wela = 0;
    dula = 1;
    P0 = table[tube1];
    dula = 0;

#2


好难搞吗,程序好难看啊,太长了,呵呵

#3


程序是新概念那本书上的,两个都没有问题,问题应该是protues软件自身的问题,对数码管的显示经常不正常,我试过很多

#4


多的那三条相当于初始化操作,初始的是相应地址的值
proteus里没有这三条语句的话 开始运行时它从软件映射的地址取值就很可能得到一个不确定的数 是由这个软件和运行环境决定的 应该叫数据堆栈吧。。。
而51的板子上没有变量储存功能 加不加那三条语句它都是 0xff

嗯,软件,仿了,不一定真。。

#5


引用 4 楼 rncjd 的回复:
多的那三条相当于初始化操作,初始的是相应地址的值
proteus里没有这三条语句的话 开始运行时它从软件映射的地址取值就很可能得到一个不确定的数 是由这个软件和运行环境决定的 应该叫数据堆栈吧。。。
而51的板子上没有变量储存功能 加不加那三条语句它都是 0xff

嗯,软件,仿了,不一定真。。


有理。。仿了不一定真

#6


引用 4 楼 rncjd 的回复:
多的那三条相当于初始化操作,初始的是相应地址的值
proteus里没有这三条语句的话 开始运行时它从软件映射的地址取值就很可能得到一个不确定的数 是由这个软件和运行环境决定的 应该叫数据堆栈吧。。。
而51的板子上没有变量储存功能 加不加那三条语句它都是 0xff

嗯,软件,仿了,不一定真。。

谢谢了。。