单片机万年历

  

目录

  

# 完整代码在最后


         因为我是初学者,所以写的代码会比较繁琐,希望大佬们可以多给我一些优化的建议。

        万年历涉及到的东西并不复杂,是由一些基础的东西堆积起来的。题目为:独立按键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();
	}
}

  • 4
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

jiojio1030

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值