以下是程序主体
/************************************
**此版本出现的BUG: **
**1.在二月份最后一天跳转到三月时, **
** 年份显示会出现不知名的数值改变 **
**2.(检测中) **
************************************/
/************************************
**自我练习 计时器 版本v0.4 **
**使用开发板:实验板LY5A-L2A **
**使用单片机:STC89C52RC **
**此版本增加了以下功能 **
**1.时间模式转换(分秒/时/月日/年)**
*************************************/
#include<reg52.h>
#define uint unsigned int
#define uchar unsigned char
sbit SMG_q = P1^0 ; //定义数码管阳级控制脚(千位)
sbit SMG_b = P1^1 ; //定义数码管阳级控制脚(百位)
sbit SMG_s = P1^2 ; //定义数码管阳级控制脚(十位)
sbit SMG_g = P1^3 ; //定义数码管阳级控制脚(个位)
sbit key1 = P3^7; //定义key1控制脚
sbit key2 = P3^6; //定义key2控制脚
sbit key3 = P3^5; //定义key3控制脚
sbit key4 = P3^4; //定义key4控制脚
uint yea;
uchar mon, day, hou, min, sec;
uchar num0, num1, num2, num3, num4;
uchar LED; //定义引用变量
uchar table[]={0xc0,0xf9,0xa4,
0xb0,0x99,0x92,
0x82,0xf8,0x80,
0x90}; //表:共阳数码管 0-9
/********************************************************************************
* 引用程序目录 *
********************************************************************************/
void delay(); //短暂延时程序
void timereset(); //时间初始设定
void bissextileyear(); //闰年判断程序
void MSdisplay(); //数码管动态显示扫描(分秒)
void Hdisplay(); //数码管动态显示扫描(小时)
void MDdisplay(); //数码管动态显示扫描(月日)
void Ydisplay(); //数码挂动态显示扫描(年)
void SMGdisplay(); //数码管显示模式切换
void LEDdisplay(); //LED显示
void re(); //T0、T1计时器初始化设置
void timeshow(); //计时器时间转换
void LEDshow(); //LED时间转换
void keyscan(); //键盘扫描
void main() //主程序
{
re();
timereset();
while(1)
{
keyscan();
timeshow();
SMGdisplay();
LEDshow();
LEDdisplay();
}
}
void delay() //短暂延时子程序
{
uint i=10;
while(i--);
}
void timereset() //时间初始设定子程序
{
sec=50;
min=59;
hou=23;
day=28;
mon=2;
yea=1900;
}
void bissextileyear() //闰年判断子程序
{
num4=yea;
if(yea%100==0) //百年判断
{
if(yea%400==0) //四百年判断
num3=1;
else
num3=0;
}
else
{
if(yea%4==0) //四年判断
num3=1;
else
num3=0;
}
yea=num4;
}
void MSdisplay() //数码管动态显示扫描(分秒)
{
SMG_q=0; //千位显示
P0=table[min/10];
delay();
P0=0xff;
SMG_q=1;
SMG_b=0; //百位显示
P0=table[min%10];
delay();
P0=0xff;
P0=0x7f;
delay();
P0=0xff;
SMG_b=1;
SMG_s=0; //十位显示
P0=table[sec/10];
delay();
P0=0xff;
SMG_s=1;
SMG_g=0; //个位显示
P0=table[sec%10];
delay();
P0=0xff;
SMG_g=1;
}
void Hdisplay() //数码管动态显示扫描(小时)
{
SMG_s=0; //十位显示
P0=table[hou/10];
delay();
P0=0xff;
SMG_s=1;
SMG_g=0; //个位显示
P0=table[hou%10];
delay();
P0=0xff;
SMG_g=1;
}
void MDdisplay() //数码管动态显示扫描(月日)
{
SMG_q=0; //千位显示
P0=table[mon/10];
delay();
P0=0xff;
SMG_q=1;
SMG_b=0; //百位显示
P0=table[mon%10];
delay();
P0=0xff;
P0=0x7f;
delay();
P0=0xff;
SMG_b=1;
SMG_s=0; //十位显示
P0=table[day/10];
delay();
P0=0xff;
SMG_s=1;
SMG_g=0; //个位显示
P0=table[day%10];
delay();
P0=0xff;
SMG_g=1;
}
void Ydisplay() //数码管动态显示扫描(年)
{
SMG_q=0; //千位显示
P0=table[yea/1000];
delay();
P0=0xff;
SMG_q=1;
SMG_b=0; //百位显示
P0=table[yea%1000/100];
delay();
P0=0xff;
SMG_b=1;
SMG_s=0; //十位显示
P0=table[yea%1000%100/10];
delay();
P0=0xff;
SMG_s=1;
SMG_g=0; //个位显示
P0=table[yea%1000%100%10];
delay();
P0=0xff;
SMG_g=1;
}
void SMGdisplay() //数码管显示模式切换
{
switch(num2)
{
case 0: MSdisplay(); break;
case 1: Hdisplay(); break;
case 2: MDdisplay(); break;
case 3: Ydisplay(); break;
}
}
void LEDdisplay() //LED显示子程序
{
P2=LED;
delay();
}
void re() //T0、T1计时器初始化设置子程序
{
TMOD=0x11;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
TH1=(65536-50000)/256;
TL1=(65536-50000)%256;
EA=1;
ET0=1;
ET1=1;
TR0=1;
TR1=1;
}
void timeshow() //计时时间转换子程序
{
if(num0==20) //计时(秒)
{
num0=0;
sec++;
if(sec==60) //计时(分)
{
sec=0;
min++;
if(min==60) //计时(时)
{
min=0;
hou++;
if(hou==24) //计时(天)
{
hou=0;
day++;
switch(mon) //月份判断
{
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
if(day==32) //计时(月)
{
if(mon==12) //计时(年)
{
mon=1;
yea++;
}
day=1;
mon++;
}
break;
case 4:
case 6:
case 9:
case 11:
if(day==31) //计时(月)
{
day=1;
mon++;
}
break;
case 2:
bissextileyear(); //闰年判断
if(num3==1) //计时(月)
{
if(day==30)
{
day=1;
mon++;
}
}
if(num3==0)
{
if(day==29)
{
day=1;
mon++;
}
}
break;
}
}
}
}
}
}
void LEDshow() //LED时间转换子程序
{
if(num1==20)
{
num1=0;
if(LED==0)
LED=0xff;
LED--;
}
}
void keyscan() //键盘检测子程序
{
if(key1==0) //key1模式设置
{
delay();
if(key1==0)
{
num2=0;
}
}
if(key2==0) //key2模式设置
{
delay();
if(key2==0)
{
num2=1;
}
}
if(key3==0) //key3模式设置
{
delay();
if(key3==0)
{
num2=2;
}
}
if(key4==0) //key4模式设置
{
delay();
if(key4==0)
{
num2=3;
}
}
}
void T0_time() interrupt 1 //T0计时器中断服务程序
{
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
num0++;
}
void T1_time() interrupt 3 //T1计时器中断服务程序
{
TH1=(65536-50000)/256;
TL1=(65536-50000)%256;
num1++;
}
/************************************
**此版本出现的BUG: **
**1.在二月份最后一天跳转到三月时, **
** 年份显示会出现不知名的数值改变 **
**2.(检测中) **
************************************/
/************************************
**自我练习 计时器 版本v0.4 **
**使用开发板:实验板LY5A-L2A **
**使用单片机:STC89C52RC **
**此版本增加了以下功能 **
**1.时间模式转换(分秒/时/月日/年)**
*************************************/
#include<reg52.h>
#define uint unsigned int
#define uchar unsigned char
sbit SMG_q = P1^0 ; //定义数码管阳级控制脚(千位)
sbit SMG_b = P1^1 ; //定义数码管阳级控制脚(百位)
sbit SMG_s = P1^2 ; //定义数码管阳级控制脚(十位)
sbit SMG_g = P1^3 ; //定义数码管阳级控制脚(个位)
sbit key1 = P3^7; //定义key1控制脚
sbit key2 = P3^6; //定义key2控制脚
sbit key3 = P3^5; //定义key3控制脚
sbit key4 = P3^4; //定义key4控制脚
uint yea;
uchar mon, day, hou, min, sec;
uchar num0, num1, num2, num3, num4;
uchar LED; //定义引用变量
uchar table[]={0xc0,0xf9,0xa4,
0xb0,0x99,0x92,
0x82,0xf8,0x80,
0x90}; //表:共阳数码管 0-9
/********************************************************************************
* 引用程序目录 *
********************************************************************************/
void delay(); //短暂延时程序
void timereset(); //时间初始设定
void bissextileyear(); //闰年判断程序
void MSdisplay(); //数码管动态显示扫描(分秒)
void Hdisplay(); //数码管动态显示扫描(小时)
void MDdisplay(); //数码管动态显示扫描(月日)
void Ydisplay(); //数码挂动态显示扫描(年)
void SMGdisplay(); //数码管显示模式切换
void LEDdisplay(); //LED显示
void re(); //T0、T1计时器初始化设置
void timeshow(); //计时器时间转换
void LEDshow(); //LED时间转换
void keyscan(); //键盘扫描
void main() //主程序
{
re();
timereset();
while(1)
{
keyscan();
timeshow();
SMGdisplay();
LEDshow();
LEDdisplay();
}
}
void delay() //短暂延时子程序
{
uint i=10;
while(i--);
}
void timereset() //时间初始设定子程序
{
sec=50;
min=59;
hou=23;
day=28;
mon=2;
yea=1900;
}
void bissextileyear() //闰年判断子程序
{
num4=yea;
if(yea%100==0) //百年判断
{
if(yea%400==0) //四百年判断
num3=1;
else
num3=0;
}
else
{
if(yea%4==0) //四年判断
num3=1;
else
num3=0;
}
yea=num4;
}
void MSdisplay() //数码管动态显示扫描(分秒)
{
SMG_q=0; //千位显示
P0=table[min/10];
delay();
P0=0xff;
SMG_q=1;
SMG_b=0; //百位显示
P0=table[min%10];
delay();
P0=0xff;
P0=0x7f;
delay();
P0=0xff;
SMG_b=1;
SMG_s=0; //十位显示
P0=table[sec/10];
delay();
P0=0xff;
SMG_s=1;
SMG_g=0; //个位显示
P0=table[sec%10];
delay();
P0=0xff;
SMG_g=1;
}
void Hdisplay() //数码管动态显示扫描(小时)
{
SMG_s=0; //十位显示
P0=table[hou/10];
delay();
P0=0xff;
SMG_s=1;
SMG_g=0; //个位显示
P0=table[hou%10];
delay();
P0=0xff;
SMG_g=1;
}
void MDdisplay() //数码管动态显示扫描(月日)
{
SMG_q=0; //千位显示
P0=table[mon/10];
delay();
P0=0xff;
SMG_q=1;
SMG_b=0; //百位显示
P0=table[mon%10];
delay();
P0=0xff;
P0=0x7f;
delay();
P0=0xff;
SMG_b=1;
SMG_s=0; //十位显示
P0=table[day/10];
delay();
P0=0xff;
SMG_s=1;
SMG_g=0; //个位显示
P0=table[day%10];
delay();
P0=0xff;
SMG_g=1;
}
void Ydisplay() //数码管动态显示扫描(年)
{
SMG_q=0; //千位显示
P0=table[yea/1000];
delay();
P0=0xff;
SMG_q=1;
SMG_b=0; //百位显示
P0=table[yea%1000/100];
delay();
P0=0xff;
SMG_b=1;
SMG_s=0; //十位显示
P0=table[yea%1000%100/10];
delay();
P0=0xff;
SMG_s=1;
SMG_g=0; //个位显示
P0=table[yea%1000%100%10];
delay();
P0=0xff;
SMG_g=1;
}
void SMGdisplay() //数码管显示模式切换
{
switch(num2)
{
case 0: MSdisplay(); break;
case 1: Hdisplay(); break;
case 2: MDdisplay(); break;
case 3: Ydisplay(); break;
}
}
void LEDdisplay() //LED显示子程序
{
P2=LED;
delay();
}
void re() //T0、T1计时器初始化设置子程序
{
TMOD=0x11;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
TH1=(65536-50000)/256;
TL1=(65536-50000)%256;
EA=1;
ET0=1;
ET1=1;
TR0=1;
TR1=1;
}
void timeshow() //计时时间转换子程序
{
if(num0==20) //计时(秒)
{
num0=0;
sec++;
if(sec==60) //计时(分)
{
sec=0;
min++;
if(min==60) //计时(时)
{
min=0;
hou++;
if(hou==24) //计时(天)
{
hou=0;
day++;
switch(mon) //月份判断
{
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
if(day==32) //计时(月)
{
if(mon==12) //计时(年)
{
mon=1;
yea++;
}
day=1;
mon++;
}
break;
case 4:
case 6:
case 9:
case 11:
if(day==31) //计时(月)
{
day=1;
mon++;
}
break;
case 2:
bissextileyear(); //闰年判断
if(num3==1) //计时(月)
{
if(day==30)
{
day=1;
mon++;
}
}
if(num3==0)
{
if(day==29)
{
day=1;
mon++;
}
}
break;
}
}
}
}
}
}
void LEDshow() //LED时间转换子程序
{
if(num1==20)
{
num1=0;
if(LED==0)
LED=0xff;
LED--;
}
}
void keyscan() //键盘检测子程序
{
if(key1==0) //key1模式设置
{
delay();
if(key1==0)
{
num2=0;
}
}
if(key2==0) //key2模式设置
{
delay();
if(key2==0)
{
num2=1;
}
}
if(key3==0) //key3模式设置
{
delay();
if(key3==0)
{
num2=2;
}
}
if(key4==0) //key4模式设置
{
delay();
if(key4==0)
{
num2=3;
}
}
}
void T0_time() interrupt 1 //T0计时器中断服务程序
{
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
num0++;
}
void T1_time() interrupt 3 //T1计时器中断服务程序
{
TH1=(65536-50000)/256;
TL1=(65536-50000)%256;
num1++;
}