目录
# 完整代码在最后
因为我是初学者,所以写的代码会比较繁琐,希望大佬们可以多给我一些优化的建议。
万年历涉及到的东西并不复杂,是由一些基础的东西堆积起来的。题目为:独立按键S7控制年,月,日,时,分,秒六个数据的选中。S6控制万年历的暂停,当万年历暂停时,S5与S4分别控制选中数据的加与减。
我们使用计时器中断来消抖和按键检测,重点:按键扫描要写在前面,而且四个键要同级,嵌套可能会出bug,比如先检测按键是否按下再判断if(现在选中的是数据年),而不是先判断if(是否选中数据年)然后才判断按键是否按下。
u8 dat;
u8 Try;
u8 Cont;
void BIN()
{
dat=P3^0XFF;
Try = dat&(dat^Cont);//中断三行代码
Cont = dat;
}
void Timer0Init(void) //100微秒@11.0592MHz
{
AUXR |= 0x80; //定时器时钟1T模式
TMOD &= 0xF0; //设置定时器模式
TL0 = 0xAE; //设置定时初值
TH0 = 0xFB; //设置定时初值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
ET0=1;
EA=1;
}
u8 diyi;
void Time0()interrupt 1
{
diyi++;
if(diyi==15)
{
diyi=0;
ZTCX=1;
}
}
void ZT()
{
if(ZTCX==1)
{
ZTCX=0;
BIN();
if(Try & 0X01)
{
当按键按下时发生什么
}
if(Try & 0X02)
{
当按键按下时发生什么
}
if(Try & 0X04)
{
当按键按下时发生什么
}
if(Try & 0X08)
{
当按键按下时发生什么
}
}
因为数码管只有八位,所以六个数据的展示需要分两个界面:
void ZT()
{
if(ZTCX==1)
{
ZTCX=0;
BIN();
if(Try & 0X01)
{
zhuangtai++;
if(zhuangtai==6)
{
zhuangtai=0;
}
}
if(zhuangtai==0||zhuangtai==1||zhuangtai==2)
{
smg[0]=tab[na/1000];
smg[1]=tab[na/100%10];
smg[2]=tab[na/10%10];
smg[3]=tab[na%10];
smg[4]=tab[yue/10];
smg[5]=tab[yue%10];
smg[6]=tab[ri/10];
smg[7]=tab[ri%10];
}
if(zhuangtai==3||zhuangtai==4||zhuangtai==5)
{
smg[0]=0XFF;
smg[1]=0XFF;
smg[2]=tab[sh/10];
smg[3]=tab[sh%10];
smg[4]=tab[fen/10];
smg[5]=tab[fen%10];
smg[6]=tab[miao/10];
smg[7]=tab[miao%10];
}
}
}
配合动态数码管:
void Time0()interrupt 1
{
disan++;
if(disan==20)
{
disan=0;
P2=0XC0;P0=0X01<<i;P2=0;
P2=0XE0;P0=smg[i]; P2=0;
i++;
if(i==8)
{
i=0;
}
}
}
我们设定每次S7按下zhuangtai这个变量就加一,每个值对应不同的数据。
还有让万年历动起来,以及S6按键控制万年历的暂停。
void ZT()
{
if(ZTCX==1)
{
ZTCX=0;
BIN();
if(Try & 0X02)
{
BHCX=~BHCX;
}
}
}
void Time0()interrupt 1
{
if(BHCX==1)
{
dier++;
if(dier==10000)
{
dier=0;
miao++;
if(miao==60)
{
fen++;
miao=0;
if(fen==60)
{
sh++;
fen=0;
if(sh==25)
{。。。。。。。}
}
}
}
}
}
编写的时候还要注意闰年和大小二月。总体来说不难,有一个思路然后一步一步来就行。完整代码放下面了,初学者第一次写博客,希望少一些谩骂,多一些建议。
# 完整代码
#include <STC15F2K60S2.H>
typedef unsigned int u16;
typedef unsigned char u8;
u8 code tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xFF};
u8 smg[8];
u8 Try;
u8 Cont;
u8 i;
u16 na=2022;
u8 sh=11,yue=11,ri=12;
signed char fen=38,miao=11;
bit ZTCX;
bit BHCX;
bit ZTDBH;
u8 dat;
void BIN()
{
dat=P3^0XFF;
Try = dat&(dat^Cont);
Cont = dat;
}
u8 zhuangtai;
u8 NIAN=0;
u8 SHI=0;
void ZT()
{
if(ZTCX==1)
{
ZTCX=0;
BIN();
if(Try & 0X02)
{
BHCX=~BHCX;
}
if(Try & 0X04)
{
if(BHCX==0)
{
if(zhuangtai==0)
{
na++;
}
if(zhuangtai==1)
{
yue++;
if(yue==13)
{
yue=1;
}
}
if(zhuangtai==2)
{
ri++;
if(yue==1||yue==3||yue==5||yue==7||yue==8||yue==10||yue==12)
{
if(ri==32)
{
ri=1;
}
}
if(yue==4||yue==6||yue==9||yue==11)
{
if(ri==31)
{
ri=1;
}
}
if(yue==2)
{
if((na%400==0)||(na%4==0&&na%100!=0))
{
if(ri==30)
{
ri=1;
}
}
else
if(ri==29)
{
ri=1;
}
}
}
if(zhuangtai==3)
{
sh++;
if(sh==25)
{
sh=1;
}
}
if(zhuangtai==4)
{
fen++;
if(fen==60)
{
fen=0;
}
}
if(zhuangtai==5)
{
miao++;
if(miao==60)
{
miao=0;
}
}
}
}
if(Try & 0X08)
{
if(BHCX==0)
{
if(zhuangtai==0)
{
na--;
}
if(zhuangtai==1)
{
yue--;
if(yue==0)
{
yue=12;
}
}
if(zhuangtai==2)
{
ri--;
if(yue==1||yue==3||yue==5||yue==7||yue==8||yue==10||yue==12)
{
if(ri==0)
{
ri=31;
}
}
if(yue==4||yue==6||yue==9||yue==11)
{
if(ri==0)
{
ri=30;
}
}
if(yue==2)
{
if((na%400==0)||(na%4==0&&na%100!=0))
{
if(ri==0)
{
ri=29;
}
}
else
if(ri==0)
{
ri=28;
}
}
}
if(zhuangtai==3)
{
sh--;
if(sh==0)
{
sh=24;
}
}
if(zhuangtai==4)
{
fen--;
if(fen==-1)
{
fen=59;
}
}
if(zhuangtai==5)
{
miao--;
if(miao==-1)
{
miao=59;
}
}
}
}
if(Try & 0X01)
{
zhuangtai++;
if(zhuangtai==6)
{
zhuangtai=0;
}
}
if(zhuangtai==0||zhuangtai==1||zhuangtai==2)
{
smg[0]=tab[na/1000];
smg[1]=tab[na/100%10];
smg[2]=tab[na/10%10];
smg[3]=tab[na%10];
smg[4]=tab[yue/10];
smg[5]=tab[yue%10];
smg[6]=tab[ri/10];
smg[7]=tab[ri%10];
}
if(zhuangtai==3||zhuangtai==4||zhuangtai==5)
{
smg[0]=0XFF;
smg[1]=0XFF;
smg[2]=tab[sh/10];
smg[3]=tab[sh%10];
smg[4]=tab[fen/10];
smg[5]=tab[fen%10];
smg[6]=tab[miao/10];
smg[7]=tab[miao%10];
}
}
}
void ALLinit()
{
P2=0X80;P0=0XFF;P2=0;
P2=0XA0;P0=0X00;P2=0;
P2=0XC0;P0=0XFF;P2=0;
P2=0XE0;P0=0XFF;P2=0;
}
void Timer0Init(void) //100微秒@11.0592MHz
{
AUXR |= 0x80; //定时器时钟1T模式
TMOD &= 0xF0; //设置定时器模式
TL0 = 0xAE; //设置定时初值
TH0 = 0xFB; //设置定时初值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
ET0=1;
EA=1;
}
u8 diyi;
u16 dier;
u8 disan;
void Time0()interrupt 1
{
diyi++;
disan++;
if(diyi==15)
{
diyi=0;
ZTCX=1;
}
if(BHCX==1)
{
dier++;
if(dier==10000)
{
dier=0;
miao++;
if(miao==60)
{
fen++;
miao=0;
if(fen==60)
{
sh++;
fen=0;
if(sh==25)
{
sh=1;
ri++;
if(yue==1||yue==3||yue==5||yue==7||yue==8||yue==10||yue==12)
{
if(ri==32)
{
ri=1;
yue++;
}
}
if(yue==4||yue==6||yue==9||yue==11)
{
if(ri==31)
{
ri=1;
yue++;
}
}
if(yue==2)
{
if((na%400==0)||(na%4==0&&na%100!=0))
{
if(ri==30)
{
ri=1;
yue++;
}
}
if(ri==29)
{
ri=1;
yue++;
}
if(yue==13)
{
yue=1;
na++;
}
}
}
}
}
}
}
if(disan==20)
{
disan=0;
P2=0XC0;P0=0X01<<i;P2=0;
P2=0XE0;P0=smg[i]; P2=0;
i++;
if(i==8)
{
i=0;
}
}
}
void main()
{
Timer0Init();
ALLinit();
while(1)
{
ZT();
}
}