51单片机可调校时钟中的问题———求大神指点迷津,带PRoteus 仿真

2019-07-15 13:02发布

/**********************************************************************************
此程序利用八位共阳数码管显示的时钟具有时钟、调时、调闹钟的功能,实现八位数码管单独
位校准,同时校准时数码管闪烁。
key4----计时开关,(主要控制TR0是1或0,即LED灯的亮或灭)。
                初始值0,按下后取反,开始计时,再按,停止计时。

key1----模式选择,标志位flg,取值1、2、0。
                初始值0,正常显示时钟走时;
                按一下,flg=1,时钟调整模式,按两下,flg=2,闹钟调整模式;
                按三下,flg=0;回到正常时钟模式。依次循环。

key2----校准位选择,标志位flg1,取值0~8.
                初始值为0;哪一位都不闪烁,哪一位都不校准;
                每按一下,则flg1+1,加到8,再按一下回到flg1=0;
                flg1=1,表示校准第一位,第一位闪烁;flg1=2,校准第二位,第二位闪烁,依次……

key3----校准控制位,控制改变每一位数码管所显示的数字,校准哪一位,则按key3改变哪一位的值。
******************************************************************************************
定时器0用来产生计时,定时器1用来控制闪烁标志位flg2
******************************************************************************************
由于匆忙,未加入闹钟,不过这不是最主要的问题。在电路实际运行中,发现一些问题不足,求大神
高手指点迷津。谢谢!!!!!!!!!!!!!!!!!!!!!!!
现象描述:
a.        上电后,按key4,启动计时;
b.        按key1,选择调校时钟,
c.        按key2,控制校准位选择
d.        按key3,改变校准位的值
e.        反复按key2,
f.        反复按key4,
g.        按Key1,使之回到正常时钟计时模式,反复按key4,;
问题:1、重复e.f两个步骤,则会出现“明明已经开启计时模式,led亮,即TR0=1,但最后一位秒位
                要十几秒才反应过来继续改变数值计时”的情况“
      2、操作g步骤,同样遇到上述问题
***********************************************************************************
疑惑 1、产生上述问题的根源是什么???这是否与启用两个定时器设置有关????
         2、使用两个定时器时应该注意哪些问题???此处我令两个定时器初值都一样,是否不当?
         3、定时器0和定时器1有中断先后优先级,初始化时是否需要配置IP???
***********************************************************************************/
#include<reg52.h>
#include<intrins.h>
#define  uchar  unsigned char       
#define  uint  unsigned int
sbit voice=P2^3;
sbit DU=P2^6;
sbit WE=P2^7;
sbit key1=P3^0;
sbit key2=P3^1;
sbit key3=P3^2;
sbit key4=P3^3;
uchar cnt;
char  flg,flg1;//flg按Key2,一次时钟调整模式flg=1,两次定闹钟调整模式flg=2,三次正常时钟模式flg=0;
                          //flg1用来选择校准位;
bit flg2;  //flg2用来闪烁标志位,bit只有0和1两种状态。
           //TR0=1,则令P1=0x00,led亮,反之,TR0=1,则令P1=0xff,led灭,便于直观看出是否启动计时
uchar shi,fen,miao;//设定时钟
uchar hour,minute,second;//设定闹钟
uchar code duan[]={
                0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x00,0x40};
//段选         0    1    2    3    4    5     6    7   8     9        A         b          C           D        E         F          灭  -                               
uchar code T_COM[]={
                0xff,0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};
//位选         灭   第一  二   三   四   五   六   七   八位               
uchar table[]={0,1,2,17,4,5,17,7,8,9,10,17,12,13,17,15,16};//显示哪一位
void delayms(char xms)
{
        uchar i,j;       
        for(i=xms;i>0;i--)
                for(j=110;j>0;j--);
}
void init()
{
        TMOD=0x11;
        TH0=(65536-46080)/256;
        TL0=(65536-46080)%256;//定时50ms
        TH0=(65536-46080)/256;
        TL0=(65536-46080)%256;//定时50ms
        EA=1;
        ET0=1;
        ET1=1;
        TR1=1;
        shi=18;
        fen=1;
        miao=0;
        DU=0;
        WE=0;
}
void keyscan()//shi+10;shi+1;fen+10;fen+1;miao+10;miao+1       
{
        if(key1==0)
        {
                delayms(10);
                if(key1==0)
                {
                        flg++;
                        if(flg>2)
                        flg=0;
                        while(!key1);
                }
        }
        if(key2==0)
        {
                delayms(10);
                if(key2==0)
                {       
                        flg1++;
                        if(flg1>8)
                        flg1=1;
                        while(!key2);
                }
        }
        if(key3==0)
        {
                delayms(10);
                if(key3==0)
                {
                        if(flg==1)
                        {
                                switch(flg1)
                                {
                                        case 1: if(shi<13)
                                                                shi+=10;
                                                        else if(shi<20&shi>13)
                                                                shi-=10;
                                                        else if(shi>20)
                                                                shi-=20;  break;
                                        case 2:        if(shi<20)
                                                        {
                                                                if(shi%10==9)
                                                                        shi-=9;
                                                                else
                                                                        shi+=1;
                                                        }
                                                        else
                                                        {
                                                                if(shi%10==3)
                                                                        shi-=3;
                                                                else
                                                                        shi+=1;
                                                        }  break;
                                        case 3: break;
                                        case 4:        if(fen>=50)
                                                                fen-=50;
                                                        else
                                                                fen+=10; break;
                                        case 5:        if(fen%10==9)
                                                                fen-=9;
                                                        else
                                                                fen+=1; break;
                                        case 6:        break;
                                        case 7:        if(miao>=50)
                                                                miao-=50;
                                                    else miao+=10; break;
                                        case 8:        if(miao%10==9)
                                                                miao-=9;
                                                        else
                                                                miao+=1; break;
                                }
                        }
                        else if(flg==2)
                        {
                                switch(flg1)
                                {
                                        case 1: if(hour<=13)
                                                                hour+=10;
                                                        else if(hour<20&hour>13)
                                                                hour-=10;
                                                        else if(hour>20)
                                                                hour-=20;  break;
                                        case 2:        if(hour<20)
                                                        {
                                                                if(hour%10==9)
                                                                        hour-=9;
                                                                else
                                                                        hour+=1;
                                                        }
                                                        else
                                                        {
                                                                if(hour%10==3)
                                                                        hour-=3;
                                                                else
                                                                        hour+=1;
                                                        }  break;
                                        case 3: break;
                                        case 4:        if(minute>=50)
                                                                minute-=50;
                                                        else
                                                                minute+=10; break;
                                        case 5:        if(minute%10==9)
                                                                minute-=9;
                                                        else
                                                                minute+=1; break;
                                        case 6:        break;
                                        case 7:        if(second>=50)
                                                                second-=50;
                                                        else
                                                                second+=10; break;
                                        case 8:        if(second%10==9)
                                                                second-=9;
                                                        else
                                                                second+=1; break;
                                }
                        }
                        while(!key3);
                }
        }
        if(key4==0)
        {
                delayms(10);
                if(key4==0)
                {       
                        TR0=~TR0;
                        while(!key4);        
                }
        }
}
void caculate()
{
                table[1]=shi/10;
                table[2]=shi%10;
                table[4]=fen/10;
                table[5]=fen%10;       
                table[7]=miao/10;
                table[8]=miao%10;
                table[9]=hour/10;
                table[10]=hour%10;  
                table[12]=minute/10;
                table[13]=minute%10;       
                table[15]=second/10;
                table[16]=second%10;
}
void display()
{
        uchar i;
        for(i=1;i<=8;i++)
        {
                WE=1;
                P0=T_COM[i];
                WE=0;
                P0=0x00;       
                DU=1;
                if(flg<2)
                {
                        if(flg1==i&&flg2==1)
                                P0=0x00;
                        else
                                P0=duan[table[i]];       
                }
                else
                {
                        if(flg1==i&&flg2==1)
                                P0=0x00;
                        else
                                P0=duan[table[i+8]];
                }
                DU=0;
                delayms(10);
                P0=0xff;       
        }
}//此处针对proteus仿真所编写,实际板子中的display程序稍微不同,此处不影响 不必深究
void main()
{
        init();
        while(1)
        {       
                keyscan();
                if(!flg)
                flg1=0;         
                keyscan();
                        if(cnt==20)
                        {
                                cnt=0;
                                miao++;       
                        }
                        if(miao>59)
                        {
                                miao=0;
                                fen++;
                        }
                        if(fen>59)
                        {
                                fen=0;
                                shi++;
                        }
                        if(shi>23)
                                shi=0;
                if(TR0)
                        P1=0x00;
                else
                        P1=0xff;         
                caculate();       
                display();
        }
}
void timer0() interrupt 1
{
        TH0=(65536-46080)/256;
        TL0=(65536-46080)%256;//定时50ms
        cnt++;       
}
void timer1() interrupt 3
{
        TH1=(65536-46080)/256;
        TL1=(65536-46080)%256;//定时50ms
        cnt++;
        if(cnt==5)
        {
                cnt=0;
                   flg2=~flg2;
        }
       
}
/* 如下为另一种显示方法,不完整,可忽略不看
void display(uchar x,y,z)
{       
        uchar i;
        for(i=1;i<=8;i++)
        {
                WE=1;
                P0=T_COM[i];
                WE=0;
                P0=0x00;       
                DU=1;
                switch(i)
                {
                        case 1:P0=duan[x/10];break;  
                        case 2:P0=duan[x%10];break;
                        case 3:P0=duan[17];break;  
                        case 4:P0=duan[y/10];break;
                        case 5:P0=duan[y%10];break;  
                        case 6:P0=duan[17];break;
                        case 7:P0=duan[z/10];break;  
                        case 8:P0=duan[z%10];break;
                }
                DU=0;
                delayms(10);
                P0=0xff;       
        }
        if(flg1==i)
        {
                WE=1;
                P0=T_COM[i];
                WE=0;
                P0=0x00;       
                DU=1;
                P0=0x00;
                DU=0;
                delayms(10)        ;
                P0=0xff;       
        }               
}
void all_display(uchar i)
{
        switch(i)
        {
                case 0:display(shi,fen,miao);break;  //正常显示时钟
                case 1:display(shi,fen,miao);break; //时钟设定
                case 2:display(hour,minute,second);break;//闹钟设定
        }
}
//all_display(flg);
*/

Proteus 仿真fangzhen_clock.rar 下载积分: 积分 -1 分
67.5 KB, 下载次数: 14, 下载积分: 积分 -1 分
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
5条回答
lilipod
1楼-- · 2019-07-15 14:07
李春明
2楼-- · 2019-07-15 19:18
这个原来曾经利用别的坛友的程序复制过一个  但是没有遇到楼主所说的情况
lilipod
3楼-- · 2019-07-15 20:17
 精彩回答 2  元偷偷看……
纯音666
4楼-- · 2019-07-16 01:44
......................................................
充满抛瓦的梁同学
5楼-- · 2019-07-16 03:35

一周热门 更多>