📄 数字钟.c
字号:
/**********************************************************************
综合实习--软件钟
**********************************************************************/
#pragma db oe
#include <reg52.h>
#include <absacc.h>
#include <string.h>
#include <stdio.h>
#include <intrins.h>
#include <MATH.H>
#define uint unsigned int
#define uchar unsigned char
#define ulong unsigned long
void display(void);
void initsiu(void);
void delay(void);
void sztz(void);
void jssz(void);
void setsz(void);
void tzszw(uchar zj);
uchar inkey(void);
uchar disdat[6];
uchar code tab[]={0x3f,0x6,0x5b,0x4f,0x66,0x6d,0x7d,0x7,0x7f,0x6f};
uint count;
uchar hour,min,sec;
uchar set_state,xsd;
sbit zsd=P1^0;
main()
{
uchar i;
for (i=0;i<6;i++)
{
disdat[i]= 0; //将显示缓存清零
}
initsiu(); //初始化单片机
set_state=0;
do
{
i=inkey(); //设置时钟
if(i==0xe0)
setsz();
jssz();
display(); //显示
if((sec & 0x01)) //指示灯闪烁
zsd=1;
else
zsd=0;
}
while(1);
}
void display(void) //六位数码管显示程序,disdat[]是要显示的内容(是0~9的数字),xsd是在那一位显示小数点
{
uchar i,disa,disb,disc;
disb = 0x00; //显示第n位
for (i=0;i<6;i++) //共显示6个数据
{
disa = disdat[i]; //显示数据
if (disa < 10)
{
P2 = disb;
disc = tab[disa]; //显示段码
if (set_state==0) //显示时钟
{
if ((i == 1) || (i == 3))
disc = disc | 0x80; //增加小数点显示
}
else //设置时显示
{
if (xsd == i)
disc = disc | 0x80; //增加小数点显示
}
P0 = disc; //送显示
delay (); //延时
P0 = 0x0;
disb++; //下一个要显示的位置
}
}
P2 = 0xff;
}
void setsz(void) //设置时间
{
uchar i,k;
set_state=1; //改变显示状态
xsd=0; //设置位置
TR0=0; //停止时钟运行
jssz(); //将现在的结果放到数组disdat[]
do
{
display(); //显示
i=inkey(); //读键
switch (i)
{
case 0xe0: //退出设置,4号键,最左
k=0xff;
break;
case 0xd0: k=0; //改变设置位置,每按下一次右移一个,3号键,次左
xsd++;
if (xsd==6)
xsd=0;
break;
case 0xb0: //加1,2号键,次右
k=0;
tzszw(0);
break;
case 0x70: //减1,2号键,最右
k=0;
tzszw(1);
break;
default:
k=0;
break;
}
}
while(k!=0xff);
set_state=0;
TR0=1;
_nop_();
}
void tzszw(uchar zj)
{
uchar j;
switch (xsd)
{
case 0:
if (zj==0)
{
disdat[0]++;
if (disdat[0]>2)
disdat[0]=0;
}
else
{
if (disdat[0]==0)
disdat[0]=2;
else
disdat[0]--;
}
hour=disdat[0]*10+disdat[1];
break;
case 1:
if (zj==0)
{
disdat[1]++;
if (disdat[0]!=2)
{
if (disdat[1]>9)
disdat[1]=0;
}
else
{
if (disdat[1]>4)
disdat[1]=0;
}
}
else
{
if (disdat[0]!=2)
{
if (disdat[1]==0)
disdat[1]=9;
else
disdat[1]--;
}
else
{
if (disdat[1]==0)
disdat[1]=4;
else
disdat[1]--;
}
}
hour=disdat[0]*10+disdat[1];
break;
case 2:
if (zj==0)
{
disdat[2]++;
if (disdat[2]>6)
disdat[2]=0;
}
else
{
if (disdat[2]==0)
disdat[2]=6;
else
disdat[2]--;
}
min=disdat[2]*10+disdat[3];
break;
case 3:
if (zj==0)
{
disdat[3]++;
if (disdat[3]>9)
disdat[3]=0;
}
else
{
if (disdat[3]==0)
disdat[3]=9;
else
disdat[3]--;
}
min=disdat[2]*10+disdat[3];
break;
case 4:
if (zj==0)
{
disdat[4]++;
if (disdat[4]>=6)
disdat[4]=0;
}
else
{
if (disdat[4]==0)
disdat[4]=6;
else
disdat[4]--;
}
sec=disdat[4]*10+disdat[5];
break;
case 5: //秒低位调整
if (zj==0)
{
disdat[5]++;
if (disdat[5]>9)
disdat[5]=0;
}
else
{
if (disdat[5]==0)
disdat[5]=9;
else
disdat[5]--;
}
sec=disdat[4]*10+disdat[5];
break;
default:
break;
}
}
void delay(void) //延时程序
{
uchar i;
for (i=0;i<201;i++)
_nop_();
}
void jssz(void) //将时钟分离送到显示缓存
{
disdat[0]=hour/10;
disdat[1]=hour%10;
disdat[2]=min/10;
disdat[3]=min%10;
disdat[4]=sec/10;
disdat[5]=sec%10;
}
void sztz(void) //时钟运行计数,每秒运行一次
{
sec++;
if(sec==60)
{
sec=0;
min++;
if (min==60)
{
min=0;
hour++;
if (hour==24)
hour=0;
}
}
}
void initsiu(void) //初始化单片机
{
TMOD=0x11; //定时器1:gate=0->TR1=1开始计数,C/T=0->对内部计数,模式1->16位计数
TH0=0X3C;
TL0=0XAF;
ET0=1; //打开定时器0中断
ET1=0; //关闭定时器1中断
TR0=1; //打开计数器0
TR1=0; //关闭计数器1
EA=1; //总中断允许
}
void inttime0(void) interrupt 1 using 1
{
TH0=0X3C; //50ms中断一次,20次为一秒,调整时间一次
TL0=0XAF;
count++;
if (count==20)
{
count=0;
sztz();
}
}
uchar inkey(void)
{
uchar jjj,keydat;
P2 = 0xff; //P2准备读入
keydat = P2; //读入键值
keydat = keydat & 0xf0; //找出四个键的值
if (keydat != 0xf0) //有键输入
{
_nop_();
_nop_();
jjj = P2; //再读,去抖动
jjj = jjj & 0xf0;
if (jjj != keydat)
keydat = 0xf0;
do
{
jjj = P2;
jjj = jjj & 0xf0;
} //等待键松手
while (jjj != 0xf0);
}
return (keydat);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -