微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > 数码管前三位显示一个跑表

数码管前三位显示一个跑表

时间:10-02 整理:3721RD 点击:
题目是这样的。数码管前三位显示一个跑表,从000到999之间以1%秒速度运行,当按下个独立键盘时跑表停止,按下第二个时计时开始,按下第三个时计数值清零从头开始。
本人编写的程序如下:
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
uchar code table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x80,0xc6,0xc0,0x86,0x8e};
uchar num,bai,shi,ge,aa;
uint temp;
void delay(uint z);
void display(uchar bai,uchar shi,uchar ge);
void init();
void keyscan();
void main()
{
        init();//初始化子程序
        while(1)
        {
        
            keyscan();
                        if(aa==1)//用中断一秒钟计时
                                {
                                        aa=0;
                                         temp++;
                                       
                                }
                        display(bai,shi,ge);//显示数字
       

        }       
}
void delay(uint z)
{
  uint x,y;
        for(x=z;x>0;x--)
                for(y=110;y>0;y--);
}
void display(uchar bai,char shi,uchar ge)
{
        if(temp==999)
            {
             temp=0;
            }
        bai=temp/100;
        shi=temp%100/10;
        ge=temp%10;
          P2=0x7f;
        P0=table[ge];
        delay(1);
        P2=0xbf;
        P0=table[shi];
        delay(1);
        P2=0xdf;
        P0=table[bai];
        delay(1);
}
void init()
{
        TMOD=0x01;
        TH0=(65536-10000)/256;
        TL0=(65536-10000)%256;
        EA=1;
        ET0=1;
        count=1;


}
void timer0() interrupt 1
{
        TH0=(65536-10000)/256;
    TL0=(65536-10000)%256;
        aa++;
}
void keyscan()
{
        uchar getkey;
    P1=0xfe;//扫描第一行
        getkey=P1;
        getkey=getkey&0xf0;//判断是否有按键按下                    
        while(getkey!=0xf0)//有按键按下进入循环,并消抖
                {
                        /*count++;
                        if(count%2!=0)
                                TR0=0;
                        if(count%2==0)
                                TR0=1;*/
                        delay(5);
                        getkey=P1;
                        getkey=getkey&0xf0;
                        while(getkey!=0xf0)
                        {
                            getkey=P1;
                               
                                switch(getkey)
                                        {
                                                case 0xee:TR0=1;
                                                        break;
                                                case 0xde:TR0=0;
                                                        break;
                                                case 0xbe:temp=0;
                                                                  
                                                        break;
                                               
                                               
                                       
                                        }
                                while(getkey!=0xf0)//松手监测,松手后程序直接跳出三层循环进入while(1)循环,继续执行程序
                                         {
                                                getkey=P1;
                                                getkey=getkey&0xf0;
                                       
                                        }
                         
                          
                        }
                }
  
}
程序设定第一个键为开始键,但是发现在程序最开始和跑表暂停后开始,按键到跑表开始显示有很长的延时,大概1秒多。这个情况,大大降低了跑表的实用性。求大神帮看看程序,怎么解决这个问题?十分感谢,万分感激!

1.显示函数有问题,显示函数改变的只有一个temp,temp是全局变量,可以不用传递,直接用函数
void display(void);
2.你的按键只有三个  判断的时候却判断4位getkey=getkey&0xf0,这个到时候也可能影响你的程序。
3.你的定时器定的是10ms一次,不是你写的1S。TH0=(65536-10000)/256;表示10MS
4.你的键盘扫描时间应该不止10MS。开始的时候扫描没有问题,定时器没有打开。
当你打开定时器后,开始定时aa开始加。再次扫描按键,这样aa就不会等于1,直到溢出。这大概就是你说的延时了。
5.我建议你的定时器中断函数要优化下,10MS扫描一次按键,10MStemp值加一次。
可以这样处理在主函数里面if(Key_Scan_10ms == 0) Key_Scan_10ms = 10;
                                     if(temp_10ms == 0)  temp_10ms = 10;
在定时器中断里面。if(Key_Scan_10ms != 0) Key_Scan_10ms--;  if(temp_10ms != 0) temp_10ms--;

按键最好还是用中断方式查询,这样响应快速

大神,求详解,我是入门级小白。

之前写的参考一下吧
用独立按键的
#include <reg52.h>
/*以1/10秒的速度从000到999,然后再重新开始计时。
按下开关1--暂停计时
按下开关2--开始计时
按下开关3--重新开始*/
#define uint unsigned int
#define uchar unsigned char
sbit dula=P2^1;
sbit wela=P2^0;
sbit key1=P3^0;
sbit key2=P3^1;
sbit key3=P3^2;
uint temp;
uchar bai,shi,ge,num;
uchar code table[]={
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71};
void display(uchar bai,uchar shi,uchar ge);
void delay(uint);
void init();
void main()
{
        init();
        while(1)
                {
                     if(key1==0)
                         TR0=0;
                         if(key2==0)
                         TR0=1;
                         if(key3==0)
                             {
                             temp=0;
                                  if(TR0!=1)
                                 TR0=1;                                 TH0=(65536-50000)/256;                                 TL0=(65536-50000)%256;
                             }
                         display(bai,shi,ge);
                }
}
void init()
{
                temp=0;
                num=0;
        TMOD=0x01;
                TH0=(65536-50000)/256;
                TL0=(65536-50000)%256;
                EA=1;
                ET0=1;
                TR0=1;
}
void timer0() interrupt 1
{
                TH0=(65536-50000)/256;
                TL0=(65536-50000)%256;
                num++;
                if(num==2)
                {
                num=0;
                temp++;
                bai=temp/100;
            shi=temp%100/10;
            ge=temp%10;
                    if(temp==999)
                        {
                        temp=0;
                        }
                 }
}
void display(uchar bai,uchar shi,uchar ge)
{
        dula=1;
                P0=table[bai];
                dula=0;               
                wela=1;
                P0=0xdf;
                wela=0;
                delay(1);
                dula=1;
                P0=0x00;
                dula=0;
                dula=1;
                P0=table[shi];
                dula=0;               
                wela=1;
                P0=0xbf;
                wela=0;
                delay(1);
                dula=1;
                P0=0x00;
                dula=0;
                dula=1;
                P0=table[ge];
                dula=0;               
                wela=1;
                P0=0x7f;
                wela=0;
                delay(1);
                dula=1;
                P0=0x00;
                dula=0;
}
void delay(uint xms)
{
      uint i,j;
          for(i=xms;i>0;i--)
               for(j=120;j>0;j--);
}

谢谢你的程序!但请问能不能改成程序刚烧进去时要按开始键跑表才开始计时,复位后也是要按开始键才能开始?

或者有相关的资料分享一下,让俺学习学习!谢谢啦

收藏一下..

简单的修改就可以了
while(1)
                {
                     if(key1==0)
                         TR0=0;
                         if(key2==0)
                         TR0=1;
                         if(key3==0)                                  
                             {
                             temp=0;                                  //复位显示0
                                 num=0;
                                  if(TR0==1)
                                 TR0=0;                                          //关闭定时器T0
                                 TH0=(65536-50000)/256;          //重新定义初值
                                 TL0=(65536-50000)%256;                               
                             }
                         bai=temp/100;                                  //循环显示
                         shi=temp%100/10;
                         ge=temp%10;
                         display(bai,shi,ge);
                }
然后再把初始化函数中的TR0=1改成TR0=0就可以了

按键最好还是用中断方式查询,这样响应快速

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top