51开发板同一程序实现数码管实现时钟显示、秒表计时。通过独立按键选择模式(时钟/秒表)、时间的重定义

本程序可以实现时间的显示以及秒表的计时两个模式,两个模式可以同时工作互不干扰。

只需选择时钟/秒表模式进行显示即可。

使用说明:

LED指示灯

D1

亮的时候表示时钟正在运行,不亮表示时钟进入调节档位
D6 不亮表示当数码管表示的是时钟模式,亮则表示当前数码管表示的是秒表模式
D8 不亮表示,秒表暂停;亮表示,秒表正在运行

独立按键
k4 模式切换(时钟/秒表)


在时钟模式下:

k1 按一次暂停时钟运行,进入更改时档位,第二次进入更改分档位,第三次进入更改秒档位,第四次启动时钟
k2 时/分/秒  数值加一
k3 时/分/秒  数值减一

在秒表模式下:

k1
k2 秒表 暂停/起动
k3 秒表清零

 实现代码:

#include<REGX52.h>
typedef unsigned char uchar;
//共阴极段码
uchar code leddata[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
//带小数点的共阴数码管段码
uchar code ledxiaoshudian[]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef};
uchar mode=0;
unsigned int Stopwatch=0,sec=55,min=59;//秒表
char s=56,m=59,h=23;
int n0=0,n1=0;
//延时函数
void Delay(unsigned int xms){
	unsigned char i, j;
	while(xms--){
		i = 2;
		j = 239;
		do{
			while (--j);
		} while (--i);
	}
}
void Timer0Init(void)		//50毫秒@12.000MHz
{
	TMOD &= 0xF0;		//设置定时器模式
	TMOD |= 0x01;		//设置定时器模式
	TL0 = 0xB0;		//设置定时初值
	TH0 = 0x3C;		//设置定时初值
	TF0 = 0;		//清除TF0标志
	TR0 = 1;		//定时器0开始计时
    EA=1;
    ET0=1;          //定时器T0中断小开关
}
void Timer1Init(void)		//1毫秒@12.000MHz
{
	TMOD &= 0x0F;		//设置定时器模式
	TMOD |= 0x10;		//设置定时器模式
	TL1 = 0x18;		//设置定时初值
	TH1 = 0xFC;		//设置定时初值
	TF1 = 0;		//清除TF1标志
	//TR1 = 1;		//定时器1开始计时
    ET1=1;          //定时器T1中断小开关
    EA=1;
    
}

//显示时钟
//由定时器0来进行计数
void display_Clock(uchar hour,uchar minute,uchar second){
    int i;
    for(i=1;i<=8;i++){
        switch(i){
           case 1: P2_4=0;P2_3=0;P2_2=0;P0=leddata[second%10];break;
           case 2: P2_4=0;P2_3=0;P2_2=1;P0=leddata[second/10];break;
           case 3: P2_4=0;P2_3=1;P2_2=0;P0=0x40;break;//显示  —
           case 4: P2_4=0;P2_3=1;P2_2=1;P0=leddata[minute%10];break;
           case 5: P2_4=1;P2_3=0;P2_2=0;P0=leddata[minute/10];break;
           case 6: P2_4=1;P2_3=0;P2_2=1;P0=0x40;break;//显示  —
           case 7: P2_4=1;P2_3=1;P2_2=0;P0=leddata[hour%10];break;
           case 8: P2_4=1;P2_3=1;P2_2=1;P0=leddata[hour/10];break;
        }
        Delay(1);
        P0=0;        //消影
    }
}
//显示秒表
//参数为当前秒表将要显示的数,由定时器1来进行计数
void display_Stopwatch(){
    int i;
    for(i=1;i<=8;i++){
        switch(i){
           case 1: P2_4=0;P2_3=0;P2_2=0;P0=leddata[Stopwatch%10];break;
           case 2: P2_4=0;P2_3=0;P2_2=1;P0=leddata[Stopwatch/10%10];break;
           case 3: P2_4=0;P2_3=1;P2_2=0;P0=leddata[Stopwatch/100%10];break;
           case 4: P2_4=0;P2_3=1;P2_2=1;P0=ledxiaoshudian[sec%10];break;
           case 5: P2_4=1;P2_3=0;P2_2=0;P0=leddata[sec/10];break;
           case 6: P2_4=1;P2_3=0;P2_2=1;P0=P0=0x40;break;
           case 7: P2_4=1;P2_3=1;P2_2=0;P0=leddata[min%10];break;
           case 8: P2_4=1;P2_3=1;P2_2=1;P0=leddata[min/10];break;
        }
        Delay(1);
        P0=0;        //消影
    }
}
void key_scan(){
 
    static uchar flag=0;
    if(P3_1==0){   //档位选择
        Delay(20);
        while(P3_1==0);
        Delay(20);
        TR0=0;//关闭T0中断请求
        flag++;
        P2_5=1;
        if(flag==4){
            P2_0=0;
           flag=0;
            TR0=1;
            }
    }
    if(P3_3==0){//模式切换按键
        Delay(20);
        while(P3_3==0);
        Delay(20);
        mode++;
        P2_5=~P2_5;//将D6作为模式的指示灯(亮着进入秒表模式,不亮就是时钟模式)
        if(mode==2)//模式切换成时钟模式
           mode=0;  
        
    }
    if(mode==0){    //时钟模式  
        if(flag!=0){
     
            switch(flag){
                case 1:if(P3_0==0){ Delay(20);while(P3_0==0);Delay(20);h++; if(h>23) h=0;}break;
                case 2:if(P3_0==0){ Delay(20);while(P3_0==0);Delay(20);m++; if(m>59) m=0;}break;
                case 3:if(P3_0==0){ Delay(20);while(P3_0==0);Delay(20);s++; if(s>59) s=0;}break;
                default:break;
            }
            switch(flag){
                case 1:if(P3_2==0){ Delay(20);while(P3_2==0);Delay(20);h--; if(h<0) h=23;}break;
                case 2:if(P3_2==0){ Delay(20);while(P3_2==0);Delay(20);m--; if(m<0) m=59;}break;
                case 3:if(P3_2==0){ Delay (20);while(P3_2==0);Delay(20);s--; if(s<0) s=59;}break;
                default:break;
            }
        }
    }else {//秒表模式
        if(P3_2==0){ Delay(20);while(P3_2==0);Delay(20);Stopwatch=0,min=0,sec=0;}/*秒表清零*/
        if(P3_0==0){ Delay(20);while(P3_0==0);Delay(20);TR1=~TR1;P2_7=~P2_7;}/*秒表 暂停/启动*/
    }
}
void main(){
    
    Timer0Init();//定时器0  初始化
    Timer1Init();//定时器1  初始化
    P2_0=0;         //时钟正常工作指示灯,正常工作时亮,反之不亮
    while(1){
        switch(mode){
           case 0:display_Clock(h,m,s);break; 
           case 1:display_Stopwatch();break;     
        }    
        key_scan();       
    } 
}
//定时器0的溢出中断函数
void timer0() interrupt 1
{
    TL0 = 0xB0;		//设置定时初值
	TH0 = 0x3C;		//设置定时初值
    n0++;
    if(n0==20)
    {
        n0=0;
        s++;
        if(s>=60)
        {
            s=0;
            m++;
           if(m>=60)
            {
                m=0;
                h++;
                if(h>=24)
                h=0;
            } 
        } 
    } 
}
//定时器1的溢出中断函数
void timer1() interrupt 3
{
    TL1 = 0x18;		//设置定时初值
	TH1 = 0xFC;		//设置定时初值
    Stopwatch++;
     if(Stopwatch>=1000){      //秒表进位
         Stopwatch=0;           
         sec++;         
         if(sec>=60){           //秒满60分进位
            sec=0;
            min++;
            if(min>=60){
                Stopwatch=0,min=0,sec=0;
            }
         } 
     }
}

 运行环境:普中51开发板。

电路如下:

猜你喜欢

转载自blog.csdn.net/yvge669/article/details/124947430