6位数码管电子时钟c语言程序,51单片机的六位数码管时钟表仿真及C程序

本帖最后由 liuda 于 2015-1-21 22:38 编辑

Proteus仿真截图

2ace79162e46aea6846fc946816e720d.png

/*****************************************************************************

程序名称:六位数码管时钟表

编译器:Keil uVision 4

程序功能:上电后,程序按初始时间开始时钟演示,时间显示按24小时制。

时间调整:按A键,显示加1,按B键,显示减1,按C键,清零

MCU:AT89C51

晶振:11.0592M

外围部件:

键盘:4按键A、B、C、D分别接在P1.0、P1.1、P1.2和P1.3上,低电平有效

A、B、C键分别控制时、分、秒的选择,D键铵下进行时间调整。

显示:4位共阴极LED,P0口送显示数据,P1口低四位位选

内部资源:

使用定时计数器1中断,用于定时及显示

警告:

1. 按键未加防抖动程序

2. 此程序经过编译并通过Proteus仿真,未通过实物检验。

作者:花落水流红,空寂萧然山——萧然

完成日期:2012/6/11

============================================================================*/

#include    //包含必要头文件

//定义按键

sbit HourAdjust = P1^0;   //时调整选择键

sbit MinuteAdjust = P1^1;  //分调整选择键

sbit SecondAdjust = P1^2;  //秒选择选择键

sbit Adjust = P1^3;    //调整键

//定义标志位

bit SecondFlag = 0;    //秒标志

bit FlashFlag = 0;    //秒闪标志

bit Second10Flag = 0;   //10秒标志

bit HourAdjustFlag = 0;   //时调整标志,A键按下置1,10秒后清0

bit MinuteAdjustFlag = 0;   //分调整标志,A键按下置1,10秒后清0

bit SecondAdjustFlag = 0;   //秒调整标志,A键按下置1,10秒后清0

unsigned char Led1,Led2,Led3,Led4,Led5,Led6;  //定义缓存

int TimeCount,Second10Count;   //定义计数器

unsigned char code LedTab[]=  //定义共阴极数码管表,0x00用于清除显示

{0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00};

void Delay100us(int Times);    //定义延时函数

//*****************************定时器中断服务程序******************************r

//程序功能:动态驱动数码管,同时完成定时功能。

void timer() interrupt 3 using 2

{

TR1 = 0;

TL1 = 0x13; TH1 = 0x2C; //重新赋值

P0 = 0x00;    //显示小时

P2 = 0xfe;

P0 = LedTab[Led1];

Delay100us(1);

P0 = 0x00;

P2 = 0xfd;

if(FlashFlag)   //秒显(1秒显,1秒隐)分前小数点

P0 = LedTab[Led2] | 0x80;

else

P0 = LedTab[Led2] & 0x7f;

Delay100us(1);

P0 = 0x00;    //显示分

P2 = 0xfb;

P0 = LedTab[Led3];

Delay100us(1);

P0 = 0x00;

P2 = 0xf7;

if(FlashFlag)   //秒显秒前小数点

P0 = LedTab[Led4] | 0x80;

else

P0 = LedTab[Led4] & 0x7f;

Delay100us(1);

P0 = 0x00;    //显示秒

P2 = 0xef;

P0 = LedTab[Led5];

Delay100us(1);

P0 = 0x00;

P2 = 0xdf;

P0 = LedTab[Led6];

Delay100us(1);

TR1 = 1;

if(TimeCount < 100)  //秒计数器

TimeCount++;

else

{

TimeCount = 0x00;

SecondFlag = 1;  //置位秒标志

if(Second10Flag) //10秒计数器

if(Second10Count < 20)

Second10Count++;

else

{

Second10Count = 0x00;  //10秒计数器清0

Second10Flag = 0;   //清除10s标志

HourAdjustFlag = 0;   //清除调整标志位

MinuteAdjustFlag = 0;

SecondAdjustFlag = 0;

}

}

}

//============================================================================

main(void)

{

//初始化

int Second = 30;  //初始化时间

int Minute = 12;

int Hour = 20;

Led1 = 0x00;   //清除显存

Led2 = 0x00;

Led3 = 0x00;

Led4 = 0x00;

Led5 = 0x00;

Led6 = 0x00;

SecondFlag = 0;

TimeCount = 0x00;

//设置定时器中断

TMOD = 0x10f;   //GATE=0             01010001

//C/T=0--定时/计数器1工作于定时方式

//M1=1;M0=0--选择工作模式1,构成最大定时器

//T0:在此程序不使用

TL1 = 0x13; TH1 = 0x2C; //指定定时时间为50ms  65536-50/(11.0592/12)=11283=2C13h

EA = 1;     //开总中断

TF1 = 0;

ET1 = 1;    //开定时器中断

TR1 = 1;    //开始计时

while(1)

{

//*****************************************************************************

//对时间进行调整程序

if(SecondFlag)

{

if(Second%2 == 0)

FlashFlag = 1;

else

FlashFlag = 0;

if(Second < 59)

Second++;

else

{

if(Minute < 59)

Minute++;

else

{

if(Hour < 23)

Hour++;

else

Hour = 0;

Minute = 0;

}

Second = 0;

}

SecondFlag = 0;

}

//-----------------------------------------------------------------------------

//*****************************************************************************

//时间调整程序

if(HourAdjustFlag)   //调整时程序

if(Second10Flag)

if(FlashFlag)  //时秒显

{

Led1 = 0x0a; //时隐

Led2 = 0x0a;

}

else

{

Led1 = Hour/10; //时显

Led2 = Hour%10;

}

else

{

Led1 = Hour/10;

Led2 = Hour%10;

}

else

{

Led1 = Hour/10;

Led2 = Hour%10;

}

if(MinuteAdjustFlag)  //调整分程序

if(Second10Flag)

if(FlashFlag)  //分秒显

{

Led3 = 0x0a;

Led4 = 0x0a;

}

else

{

Led3 = Minute/10;

Led4 = Minute%10;

}

else

{

Led3 = Minute/10;

Led4 = Minute%10;

}

else

{

Led3 = Minute/10;

Led4 = Minute%10;

}

if(SecondAdjustFlag)  //调整秒程序,控制秒显

if(Second10Flag)

if(FlashFlag)

{

Led5 = 0x0a;

Led6 = 0x0a;

}

else

{

Led5 = Second/10;

Led6 = Second%10;

}

else

{

Led5 = Second/10;

Led6 = Second%10;

}

else

{

Led5 = Second/10;

Led6 = Second%10;

}

if(!HourAdjust)    //时调整按键按下

{

while(!HourAdjust);  //等待松开

HourAdjustFlag = 1;  //置位时标志位

MinuteAdjustFlag = 0; //清除分标志位

SecondAdjustFlag = 0; //清除秒标志位

Second10Flag = 1;  //置位10秒标志位

}

if(!MinuteAdjust)   //分调整键按下

{

while(!MinuteAdjust);

MinuteAdjustFlag = 1;

HourAdjustFlag = 0;

SecondAdjustFlag = 0;

Second10Flag = 1;

}

if(!SecondAdjust)   //秒调整键按下

{

while(!SecondAdjust);

SecondAdjustFlag = 1;

HourAdjustFlag = 0;

MinuteAdjustFlag = 0;

Second10Flag = 1;

}

if(!Adjust)     //调整键按下

{

while(!Adjust);

if(HourAdjustFlag)  //调整时,加1

if(Hour < 23)

{

Hour++;

Second10Count = 0;

}

else

Hour = 0;

if(MinuteAdjustFlag) //调整分,加1

if(Minute < 59)

{

Minute++;

Second10Count = 0;

}

else    //调整秒,清零

Minute = 0;

if(SecondAdjustFlag)

Second = 0;

}

}

}

//********************************延时程序************************************

void Delay100us(int Times)

{

Times = Times * 100;

while(Times--);

}

//必要说明,定时器中断函数是经过计算的50ms,但在使用Proteus仿真时时间不准确。

//比实际表要快。对此不进行调整,因为中断函数是经过硬件检验通过的。