C51单片机实现六位数码管时钟

这篇博客介绍了如何使用C51单片机设计一个六位数码管显示的时钟,通过数码管的dot分隔时、分、秒。在时间设置过程中,SET键用于切换小时和分钟设定,CHANGE键用于更改数值,SET S键可将秒数清零。博主分享了实现这一功能的C语言代码。

C51单片机六位数码管时钟

用数码管dot分隔时分秒

用三个按键设置时间:

SET键:小时设定->分钟设定->结束设定,小时设定状态时表示小时的两位数码管闪烁,分钟设定时表示分钟的两位数码管闪烁

CHANGE键:在小时设定状态和分钟设定状态改变数值

SET S键:秒置零


C语言代码:

//main.c

#include <REGX52.H>
typedef unsigned int UINT  ;
typedef unsigned char UCHAR	;
#define KEY P2
#define KEYMASK   0x07  
sbit LE1 = P2^6;  //定义位控口			
sbit LE2 = P2^7;  //定义段控口
UCHAR KeyPressDown = 0x00;  
UCHAR KeyRelease = 0x00;  
UCHAR LastKey = 0x00;  
UCHAR MODE ; 
extern UCHAR HH;
extern UCHAR MM;
extern UCHAR SS;
extern bit T_CYCLE  ;
extern void T0_Init(void);	//初始化定时器,函数定义在Timer.c
UCHAR code NUM[] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};

void delay(UINT t) //延时t时钟周期
{
	while (t--)	;
}

void H_Increase(void)	//小时增1
{
	if(HH<23) HH++;
	else 
	{
		HH = 0;
	}
}

void M_Increase(void)  //分钟增1
{
	if(MM<59) MM++;
	else 
	{
		MM = 0;
		H_Increase();
	}
}

void S_Increase(void)  //秒增1
{
	if(SS<59) SS++;
	else 
	{
		SS = 0;
		M_Increase();
	}
}

void display(UCHAR SEG,UCHAR Digi) //显示一位数码管,SEG = 0-9数字,Digi = 第0-6位
{
	LE2 = 1;
	P0 = (0x01<<Digi) ;
	LE2 = 0;
	P0 = 0x00;
	LE1 = 1;
	P0 = NUM[SEG];
	if (Digi==1||Digi==3) P0 &= 0x7f	;  //显示分隔符
	delay(50);
	P0 = 0xff;
	LE1 = 0;
}

void main(void)
{
    P0 = 0xff;
    LE1 = 0;
    LE2 = 0;
	T0_Init();
    while(1)
	{
		if(MODE != 1 || T_CYCLE)
		{
			display(HH/10,0);  //显示小时十位数
			display(HH%10,1);  //显示小时个位数
		}
		if(MODE != 2  || T_CYCLE)
		{
			display(MM/10,2);  //显示分钟十位数
			display(MM%10,3);  //显示分钟个位数
		}
		display(SS/10,4);  //显示秒十位数
		display(SS%10,5);  //显示秒个位数
	}
}

void key_Process(void)	 	//按键处理程序
{
    UCHAR CurrKey;  
    KEY |= KEYMASK;  //将按键对应的IO设置为输入状态  
    CurrKey = (~KEY) & KEYMASK;  
  
    KeyPressDown = (~LastKey) & CurrKey;  
    KeyRelease = LastKey & (~CurrKey);  
  
    LastKey = CurrKey; 
	switch(KeyRelease)
	{
		case 1:
			 if(MODE == 2) MODE = 0;
			 else MODE ++;
			 break;
		case 2:
			 if(MODE == 1) H_Increase() ;
			 if(MODE == 2) M_Increase() ;
			 break;
		case 4: 
			 SS = 0;
			 break;
		default: break;
	}
}


//Timer.c

#include <reg52.h>
typedef unsigned int UINT  ;
typedef unsigned char UCHAR	;
UCHAR HH = 14;	 //小时初始值
UCHAR MM = 2;	 //分钟初始值
UCHAR SS = 55;	 //秒初始值
UINT u_10ms  = 0; //10ms计数
bit T_CYCLE = 0;
extern void key_Process(void);
extern void S_Increase(void);

void T0_Init(void)
{
	TMOD &= 0xf0;
	TMOD |= 0x01;
	//定时器赋初始值,定时时间为10ms。
	TH0 = 0xd8;
	TL0 = 0xf0;
	TR0 = 1;
	IE = 0x82;

}

void T0_INTSrv(void) interrupt 1
{
	//定时器重新开始计时。
	TH0 = 0xd8;
	TL0 = 0xf0;
	u_10ms ++;
	if (u_10ms%20==0)	// 200 ms 
	{
		T_CYCLE = !	T_CYCLE; //闪烁循环
	}
	if (u_10ms>99)	// 1000 ms = 1 second
	{
		u_10ms = 0;
		S_Increase();
	}
	key_Process();	//SET按键处理
}

Proreus仿真电路:




评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值