1、/*/* 电子日历,有时间显示、闹铃、日期、秒表及键盘设置功能/* 功能键A: 设置位数字+1 闹钟模式下为闹钟开关 秒表模式下为记时开关/* 功能键B: 设置位数字-1/* 功能键C:设置模式及设置位选择 秒表模式下为清零键 */* 功能键D:在四种工作模式下切换 设置闹钟开关#include/*这里设置程序初始化时显示的时间*/#define SET_HOUR 12/*设置初始化小时*/#define SET_MINUTE 00/*设置初始化分钟*/#define SET_SECOND 00/*设置初始化秒数*/*系统地址*/#define BASE_PORT 0x8000/*选通基地址*
2、/#define KEY_LINE BASE_PORT+1/*键盘行线地址*/#define KEY_COLUMN BASE_PORT+2/*键盘列线地址*/#define LED_SEG BASE_PORT+4/*数码管段选地址*/#define LED_BIT BASE_PORT+2/*数码管位选地址*/#define LED_ON(x) XBYTELED_BIT=(0x01#define LED_OFF XBYTELED_SEG=0x00/*LED显示空*/x)/*在设置模式下对秒分时的宏定义*/#define SECOND 0 /*对应数码管右边两位*/#define MINUTE 1
3、 /*对应数码管中间两位*/#define HOUR 2 /*对应数码管左边两位*/*定义四种工作模式*/#define CLOCK clockstr /*时钟模式*/#define ALART alartstr /*闹钟模式*/#define DATE datestr /*日期模式*/#define TIMER timerstr /*秒表模式*/*以下是所有子函数的声明*/void sys_init(void); /*系统的初始化程序*/void display(void);/*动态刷新一次数码管子程序*/void clockplus(void);/*时间加1S的子程序*/void upda
4、te_clockstr(void);/*更新时间显示编码*/void update_alartstr(void); /*更新闹钟时间的显示编码*/void update_datestr(void);/*更新日期显示编码*/void update_timerstr(void); /*更新秒表时间的显示编码*/void deley(int); /*延时子程序*/void update_dispbuf(unsigned char *);/*更新显示缓冲区*/unsigned char getkeycode(void);/*获取键值子程序*/void keyprocess(unsigned char)
5、;/*键值处理子程序*/unsigned char getmonthdays(unsigned int,unsigned char);/*计算某月的天数子程序*/*功能键功能子函数*/void Akey(void); /*当前设置位+1 开关闹钟 开关秒表*/void Bkey(void); /*当前设置位-1 开关闹钟 */void Ckey(void); /*设置位选择 秒表清零*/void Dkey(void); /*切换四种工作模式*/*全局变量声明部分*/unsigned char led10=0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,
6、0x6F;/*从09的LED编码*/unsigned char ledchar3=0x5c,0x54,0x71;/*o n f*/unsigned char key24=/* 键值代码数组 对应键位:*/0x70,0x71,0x72,0x73,0x74,0x75, 7 8 9 A TRACE RESET*/0xb0,0xb1,0xb2,0xb3,0xb4,0xb5, 4 5 6 B STEP MON */0xd0,0xd1,0xd2,0xd3,0xd4,0xd5, 1 2 3 C HERE LAST */0xe0,0xe1,0xe2,0xe3,0xe4,0xe5; 0 F E D EXEC N
7、EXT */struct/*时间结构体变量*/unsigned char s;unsigned char m;unsigned char h;clock=SET_SECOND,SET_MINUTE,SET_HOUR; /*闹铃时间结构体变量*/alart=SET_MINUTE,SET_HOUR; /*日期结构体变量*/ unsigned int year; unsigned char month; unsigned char day; date=6,1,1; /*秒表时间结构体变量*/ unsigned char ms; unsigned char s; unsigned char m; ti
8、mer=0,0,0;unsigned char dispbuf6;/*显示缓冲区数组*/unsigned char clockstr6;/*时间显示的数码管编码数组*/unsigned char alartstr6;/*闹钟显示的数码管编码数组*/unsigned char datestr6;/*日期显示的数码管编码数组*/unsigned char timerstr6; /*秒表显示的数码管编码数组*/unsigned int itime=0,idot;/*定时器0中断计数*/unsigned char itime1=0;/*定时器1中断计数*/sbit P3_1=P31;/*外接蜂鸣器的管
9、脚*/bdata bit IsSet=0;/*设置模式标志位:正常走时 :设置模式*/bdata bit Alart_EN=0;/*闹铃功能允许位 :禁止闹铃 :允许闹铃*/bdata bit IsBeep=0; /*响铃标志位未响铃 :正在响铃*/unsigned char SetSelect=0;/*在设置模式IsSet=1时,正在被设置的位,对应上面的宏*/unsigned char *CurrentMode; /*标志当前正设置的功能,如CurrentMode=CLOCK或CurrentMode=ALART等*/void timerplus(void);/*函数部分*/void mai
10、n(void) sys_init();XBYTEKEY_COLUMN,0x00;/*给键盘列线赋全零扫描码,判断是否有键按下while(XBYTEKEY_LINE&0x0f)=0x0f)/*检测是否有键按下,无则一直进行LED的刷新显示*/ if(Alart_EN&(clock.h=alart.h)&(clock.m=alart.m) IsBeep=1; else IsBeep=0; P3_1=0; display();keyprocess(getkeycode();/*有键按下时得到键值,并送入键值处理程序*/*可要可不要*/void sys_init(void)TMOD=0x22;/*定时
11、器0和1都设置为工作方式2,基准定时2502500us=0.5ms*/TH0=6; /*定时器0中断服务用来产生1秒时钟定时及闹钟蜂鸣器蜂鸣脉冲*/TL0=6; /*定时器1中断服务留给秒表使用,产生1/100秒定时*/ TH1=6; TL1=6; ET0=1; ET1=1; EA=1;TR0=1; update_clockstr(); /*初始化时钟显示编码数组*/ update_alartstr(); /*初始化闹钟显示编码数组*/ update_datestr(); /*初始化日期显示编码数组*/ update_timerstr(); /*初始化秒表显示编码数组*/ update_dis
12、pbuf(clockstr);/*初始化显示缓冲数组*/ CurrentMode=CLOCK; /*默认的显示摸式为时钟*/ /*蜂鸣器接线引脚复位*/void timer0(void) interrupt 1 using 1 /*定时器0中断服务器,用来产生1秒定时*/itime+;if(itime=1000) if(IsSet) /*在设置模式下,对正在设置的位闪烁显示*/ dispbufSetSelect*2=0; /*对正在设置的位所对应的显示缓冲区元素赋0,使LED灭*/ dispbufSetSelect*2+1=0; if(IsBeep) P3_1=!P3_1;/*闹钟模式时,产生
13、峰鸣器响脉冲*/ if(CurrentMode=CLOCK) dispbuf2=dispbuf2&0x7f; dispbuf4=dispbuf4&if(itime=2000)/*两千次计数为1S 20000.5ms=1s*/ itime=0;/*定时1s时间到,软计数清零*/ clockplus();/*时间结构体变量秒数加1 */* 更新时间显示编码数组 */ if(CurrentMode!=TIMER) update_dispbuf(CurrentMode);/* 用时间编码数组更新显示缓冲区 */void timer1(void) interrupt 3 using 2 /*定时器1中断
14、服务器,用来产生1/100秒定时*/idot+;if(+itime1=20) /*20*0.5ms=10ms*/ itime1=0; timerplus(); if(CurrentMode=TIMER) update_dispbuf(timerstr); /*关闭小数点的显示*/ if(idot1000) /*闪烁显示小数点*/ dispbuf2=dispbuf2|0x80; dispbuf4=dispbuf4|0x80; elseif(idot=2000) idot=0;/*功能模块子函数*/void clockplus(void)/*时间加1s判断分,时子函数*/if(+clock.s=6
15、0)/*秒位判断*/clock.s=0;if(+clock.m=60)/*分位判断*/ clock.m=0; if(+clock.h=24)/*时位判断*/ clock.h=0; if(+date.day=(getmonthdays(date.year,date.month)+1) date.day=1; if(+date.month=13) date.month=1;void timerplus() /*秒表1/100秒位加1,判断秒、分子程序*/if(+timer.ms=100) timer.ms=0; if(+timer.s=60) timer.s=0; if(+timer.m=60)
16、timer.m=0; void update_clockstr(void)/*更新时钟显示代码数组clockstr*/clockstr0=ledclock.s%10;/*给元素0赋相应数码管显示编码,编码序号是秒数的个位*/clockstr1=led(int)(clock.s/10);/*给元素1赋相应数码管显示编码,编码序号是秒数的十位*/clockstr2=ledclock.m%10;/*以下类推*/clockstr3=led(int)(clock.m/10);clockstr4=ledclock.h%10;clockstr5=led(int)(clock.h/10);void updat
17、e_alartstr(void) /*更新闹钟显示代码数组alartstr*/ /*右边两位显示on:闹钟开启 of:闹钟关闭*/ if(Alart_EN) alartstr0=ledchar1;/*显示字母n*/ else alartstr0=ledchar2; /*显示字母f*/ alartstr1=ledchar0; /*显示字母o*/ alartstr2=ledalart.m%10; alartstr3=led(int)(alart.m/10); alartstr4=ledalart.h%10; alartstr5=led(int)(alart.h/10);void update_da
18、testr(void) /*更新日期显示代码数组datestr*/ datestr0=leddate.day%10; datestr1=led(int)(date.day/10); datestr2=leddate.month%10; datestr3=led(int)(date.month/10); datestr4=leddate.year%10; datestr5=led(int)(date.year/10);void update_timerstr(void) /*更新秒表显示代码数组timerstr*/ timerstr0=ledtimer.ms%10; timerstr1=led(
19、int)(timer.ms/10); timerstr2=ledtimer.s%10; timerstr3=led(int)(timer.s/10); timerstr4=ledtimer.m%10; timerstr5=led(int)(timer.m/10);void display(void) /*刷新显示六位LED一次*/unsigned char i;for(i=0;i6;i+)LED_ON(i);/*选通相应位*/XBYTELED_SEG=dispbufi;/*写显示段码*/ deley(50);/*延时显示*/LED_OFF;/*写LED全灭段码*/void update_dis
20、pbuf(unsigned char *str) /*更新显示缓冲区子函数,参数为要用来更新缓冲区的源字符数组的首地址*/ dispbuf0=str0;/*将要更新的源字符数组内容COPY至dispbuf数组,用作显示缓冲区*/ dispbuf1=str1; dispbuf2=str2|0x80; /*默认把时位和分位后面的小数点显示出来,根据需要再取舍*/ dispbuf3=str3; dispbuf4=str4|0x80; dispbuf5=str5;void deley(int i) /*延时子函数*/while(i-);unsigned char getkeycode(void)/*键盘扫描子程序,返回获得的键码*/unsigned char keycode;/*键码变量,一开始存行码*/unsigned char scancode=0x
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1