/*yy C program
*硬件描述:P0口接共阳数码管,a-P0.0……dp-P0.7,P1.7、P1.6、P1.5、P1.4为位码,
输出低电平有效,s41接P3.4,切换键,s40接P3.3,输入键。
功能:输入年份和月份后计算该月的天数,s41键做状态设定(输入年、月、显示天数的切换,
s40键用作输入键。开机后按s40输入年份低两位,按下s41键,输入年份的高两位,再按下s41键
输入月份,再按下s41键,显示该月份的天数。
参考:《电子制作2006》
完整代码下载地址: http://www.51hei.com/ziliao/file/yuef.rar */
#include <reg51.h>
#define uchar unsigned char
#define uint unsigned int
uchar code SEG7[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,};
sbit P17=P1^7;//千位
sbit P16=P1^6;//百位
sbit P15=P1^5;//十位
sbit P14=P1^4;//个位
sbit P33=P3^3;
sbit P34=P3^4;
uchar ACT[4]={0xef,0xdf,0xbf,0x7f};//数码管的位选码
//=================================
uchar status_flag;
uint year;
uchar month;
uchar day;
uchar temp_year_l,temp_month;
uchar temp_year_h;
//=================================
void delay(uint k)
{
uint i,j;
for(i=0;i<k;i++)
{
for(j=0;j<121;j++)
{;}
}
}
//=================================
void key_s41()
{
P3=0xff;
if(P3==0xef)status_flag++;
if(status_flag>3)status_flag=0;//status变化范围0~3(只能输入年份低位、年份高位、月份和显示天数4种状态)
}
//=================================
void key_s40()
{
P3=0xff;
if(P3==0xf7)
{
switch(status_flag)
{
case 0:temp_year_l++; //status_flag为0,为年份低两位输入状态
if(temp_year_l>99)temp_year_l=0;break;
case 1:temp_year_h++; //status_flag为1,为年份高两位输入状态
if(temp_year_h>99)temp_year_h=0;break;
case 2:temp_month++; //status_flag为2,为月份输入状态
if(temp_month>12)temp_month=1;break;
default:break;
}
}
}
uchar conv(uint year,uchar month)
{
uchar len;
switch(month)
{
case 1:len=31;break;
case 3:len=31;break;
case 5:len=31;break;
case 7:len=31;break;
case 8:len=31;break;
case 10:len=31;break;
case 12:len=31;break;
case 4:len=30;break;
case 6:len=30;break;
case 9:len=30;break;
case 11:len=30;break;
case 2:if(year%4==0&&year%100!=0||year%400==0)len=29;
else len=28;break;
default:return 0;break;//如果输入月份出错,天数返回0
}
return len;
}
void main()
{
uchar i;
uint temp1,temp2;
while(1)
{
key_s41();//P41(p3.4)切换键,为0时输入年份低两位,为1时输入年份高两位,为2时输入月份
switch(status_flag)
{
case 0:key_s40();//p3.3,输入键
temp1=temp_year_l;
case 1:key_s40();
temp2=temp_year_h;
case 2:key_s40();
month=temp_month;break;
default:break;
}
year=temp1+(temp2*100);
day=conv(year,month);
for(i=0;i<40;i++)
{
switch(status_flag)
{case 0:
case 1: P0=SEG7[year%10];
P1=ACT[0];delay(1);
P0=SEG7[(year%100)/10];
P1=ACT[1];delay(1);
P0=SEG7[(year/100)%10];
P1=ACT[2];delay(1);
P0=SEG7[year/1000];
P1=ACT[3];delay(1);break;
case 2:P0=SEG7[month%10];
P1=ACT[0];delay(1);
P0=SEG7[month/10];
P1=ACT[1];delay(1);break;
case 3:if(day)
{
P0=SEG7[day%10];
P1=ACT[2];delay(1);
P0=SEG7[day/10];
P1=ACT[3];delay(1);break;
}
else
{P0=0x00,P1=0x0f;delay(400);
P0=0xff,P1=0xff;delay(400);
P0=0x00,P1=0x0f;delay(400);
P0=0xff,P1=0xff;delay(400);
}break;//返回天数为说明出错,数码管闪烁
default :break;//一项也不符合,则直接退出
}
}
}
}
