C/C++ code#include<reg52.h>#include<stdlib.h>#define UCHAR unsigned char#define UINT unsigned intvoid init();void delay(UINT);void displayWeek(UCHAR week);void displayTime(UCHAR first, UCHAR second);void writeCmd(UCHAR cmd);void writeData(UCHAR dat);UCHAR keyscan();void keyUpDown(UCHAR *value, bit up, bit down);bit processDayMon(UCHAR *day, UCHAR *month);void display(UCHAR *seconds, UCHAR *minute, UCHAR *hour, UCHAR *day, UCHAR *week, UCHAR *month, bit displayOn);UCHAR getWeek(UCHAR day, UCHAR month, UINT year);void timeUpdate(UCHAR *value, UCHAR *nextValue, UCHAR largest, UCHAR smallest);void displayCounter(UCHAR *minute, UCHAR *seconds, UCHAR *tenMs);void recoverClock();void update(); sbit rs = P1^1; //rs 数据/命令选择端 sbit lcden = P1^2;sbit beep = P1^0;UCHAR seconds,minute,hour, week, day, month; UCHAR alarmMinute, alarmHour;UCHAR countMinute, countSeconds, countTenMs;UCHAR keyValue, key1Times, key2Times, key3Times, key5Times, key6Times, key7Times, key9Times;UINT year;UINT cnt0, cnt1; bit leapYear, alarmOn;bit flagTimer0, flagTimer1;bit timeUp, timeDown;UCHAR code weekTable[][3] = {"Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"};UCHAR code monthTable[][12] = { {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}};void main(){ init(); while(1) { update(); }}void update(){ keyValue = keyscan(); switch(keyValue) { case 1:while(keyscan() == 1); //等待按键松开 if(++key1Times == 2) //第二次按下恢复时钟界面 { key1Times = 0; recoverClock(); break; } writeCmd(0x01); //第一次按下清屏 displayCounter(&countMinute, &countSeconds, &countTenMs);//初始化计时界面 break; case 2:while(keyscan() == 2);if(++key2Times == 7)key2Times = 0;break; case 3:while(keyscan() == 3); if(++key3Times == 3) { key3Times = 0; beep = 1; //关闭闹钟 writeCmd(0x80 + 0x4e); //第二次按下清除 "On"标记 writeData(' '); writeData(' '); } break; case 5:while(keyscan() == 5);timeUp = 1;break; case 6:while(keyscan() == 6);timeDown = 1;break; case 7:while(keyscan() == 7);if(++key7Times == 3)key7Times = 0;break; case 9:while(keyscan() == 9);if(++key9Times == 3)key9Times = 1;break; } keyValue = 0; if(flagTimer0) /*每增加一秒时刷新时间变量 */ { flagTimer0 = 0; seconds++; if(key3Times != 1 && key1Times != 1) //在时钟状态下才刷新时间变量及其屏幕显示 display(&seconds, &minute, &hour, &day, &week, &month, 1); else //仅刷新时间变量,不刷新显示 display(&seconds, &minute, &hour, &day, &week, &month, 0); } /*当调整时间时,根据按下key2键的次数 *将光标移到相应的位置进行闪烁 */ if(key2Times && key3Times != 1 && key1Times != 1) //在时钟状态下按下key2 { writeCmd(0x0f); //显示光标 switch(key2Times) //根据按下key2Times的次数把光标移到相应的位置进行闪烁 { case 1:writeCmd(0x80 + 0x4a); //光标移到秒处进行闪烁 keyUpDown(&seconds, timeUp, timeDown); break; case 2:writeCmd(0x80 + 0x47);//分 keyUpDown(&minute, timeUp, timeDown); break; case 3:writeCmd(0x80 + 0x44); //时 keyUpDown(&hour ,timeUp, timeDown); break; case 4:writeCmd(0x80 + 0x0a); //日 keyUpDown(&day, timeUp, timeDown); break; case 5:writeCmd(0x80 + 0x07); //月 keyUpDown(&month, timeUp, timeDown); break; case 6:writeCmd(0x80 + 0x04); //年 if(timeUp == 1) //加一 year++; else if(timeDown == 1) //减一 year--; break; case 7:writeCmd(0x0c);key2Times = 0;break; //正常显示时钟 } if(timeUp || timeDown) //如果有按下调整时间的键盘则刷新时间 { display(&seconds, &minute, &hour, &day, &week, &month, 1); timeUp = timeDown = 0; //刷新完时间后让调整时间的变量标记归0 } } if(key3Times == 1) //第一次按下设置闹钟时间 { writeCmd(0x0c); writeCmd(0x80 + 0x4d); writeData('S'); //显示"Set",进入设置闹钟界面 writeData('e'); writeData('t'); writeCmd(0x0f); switch(key7Times) { case 1:writeCmd(0x80 + 0x47);//进入设置分的状态 keyUpDown(&alarmMinute, timeUp, timeDown); break; case 2:writeCmd(0x80 + 0x44); //时 keyUpDown(&alarmHour ,timeUp, timeDown); break; } if(timeUp || timeDown) { timeUpdate(&alarmMinute, &alarmHour, 59, 0); if(alarmHour == 24) alarmHour = 0; writeCmd(0x80 + 0x47); displayTime(alarmMinute / 10, alarmMinute % 10); writeCmd(0x80 + 0x44); displayTime(alarmHour / 10, alarmHour % 10); timeUp = timeDown = 0; } } else if(key3Times == 2) //设置好闹钟返回时钟界面并开启闹钟 { writeCmd(0x0c); writeCmd(0x80 + 0x4d); writeData(' '); writeData('O'); //显示"On",提示闹钟已开启 writeData('n'); if(alarmMinute == minute && alarmHour == hour) { alarmOn = 1; //闹钟时间到了 } if(alarmOn == 1) { beep = ~beep; delay(rand() % 100); //超时三分钟自动关闭闹钟 if(hour == alarmHour && minute - alarmMinute > 2) { alarmOn = 0; } else if(hour > alarmHour && minute + 60 - alarmMinute > 2) { alarmOn = 0; } } } if(key1Times) //计时器界面 { //displayCounter(&countMinute, &countSeconds, &countTenMs); if(key9Times == 1) { TR1 = 1; if(flagTimer1) { countTenMs++; displayCounter(&countMinute, &countSeconds, &countTenMs); flagTimer1 = 0; } } else if(key9Times == 2) { TR1 = 0; } } } void writeCmd(UCHAR cmd){ rs = 0; //命令选择端 P0 = cmd; lcden = 1; delay(1); lcden = 0; }void writeData(UCHAR dat){ rs = 1; //数据选择端 P0 = dat; lcden = 1; delay(1); //延时让数据写到液晶上去 lcden = 0; } void init(){ alarmOn = 0; alarmHour = 12; alarmMinute = 1; countMinute = countSeconds = countTenMs = 0; TMOD = 0X11; EA = 1; ET0 = 1; ET1 = 1; TR0 = 1; writeCmd(0x38); //设置显示模式 writeCmd(0x0c); //设置显示开关及光标 /*下面初始化时间变量 *2010-05-26 Wed 12:00:00 */ year = 2010; month = 5; day = 26; week = 3; //星期三 hour = 12; minute = 0; seconds = 0; leapYear = (year % 4 == 0 && year % 100 != 0 || year % 400 == 0); /*初始化时液晶显示 */ writeCmd(0x80 + 0x02); displayTime(year / 1000, year / 100 % 10); displayTime(year % 100 / 10, year % 10); writeData('-'); displayTime(month / 10, month % 10); writeData('-'); displayTime(day / 10, day % 10); writeData(' '); //光标向前移动一 位 displayWeek(week); writeCmd(0x80 + 0x44); displayTime(hour / 10, hour % 10); writeData(':'); displayTime(minute / 10, minute % 10); writeData(':'); displayTime(seconds / 10, seconds % 10); } void timer0() interrupt 1{ TH0 = (65536 - 46080) / 256; //定时时间为50ms TL0 = (65536 - 46080) % 256; if(++cnt0 == 20) { cnt0 = 0; flagTimer0 = 1; } }void timer1() interrupt 3{ TH0 = (65536 - 9216) / 256; //定时时间为 10ms; TL0 = (65536 - 9216) % 256; if(++cnt1 == 1) { cnt1 = 0; flagTimer1 = 1; }} void delay(UINT ms){ UINT x, y; for(x = ms; x; x--) for(y = 197; y; y--) ;}