/*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.zg4o1577.cn/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;//一項也不符合,則直接退出 } } } }