- #include <reg51.h>
 
- #include <stdio.h>
 
- #include "MacroAndConst.h"
 
 
- //¶¨Ò嶨ʱÆ÷0µÄ֨װֵ
 
- #define RELOAD_HIGH 0x3C
 
- #define RELOAD_LOW  0xD2
 
 
- //¶¨Òå°´¼üµ¯ÌøÊ±¼ä
 
- #define DB_VAL        10
 
 
- //¶¨ÒåÉèÖÃģʽµÄ×î´óʱ¼ä¼ä¸ô
 
- #define TIMEOUT 200
 
 
- //¶¨Òå¹â±êλÖó£Êý
 
- #define HOME 0
 
- #define HOUR 1
 
- #define MIN  2
 
- #define SEC  3
 
 
- //¶¨Òå¹â±ê״̬³£Êý
 
- #define OFF 0
 
- #define ON  1
 
 
- //¶¨ÒåÏÔʾÃüÁî³£Êý
 
- #define DISP_BUSY   0x80
 
- #define DISP_FUNC   0x38
 
- #define DISP_ENTRY  0x06
 
- #define DISP_CNTL   0x080
 
- #define DISP_ON     0x04
 
- #define DISP_CURSOR 0x02
 
- #define DISP_CLEAR  0x01
 
- #define DISP_HOME   0x02
 
- #define DISP_POS    0x80
 
- #define DISP_LINE2  0x40
 
 
- sbit SET         = P3^4;                //ÉèÖð´¼üÊäÈë
 
- sbit SELECT = P3^5;                //Ñ¡Ôñ°´¼üÊäÈë
 
- sbit ENABLE = P3^1;                //ÏÔʾʹÄÜÊä³ö
 
- sbit REGSEL = P3^7;                //ÏÔʾ¼Ä´æÆ÷Ñ¡ÔñÊä³ö
 
- sbit RDWR   = P3^6;                //ÏÔʾģʽÊä³ö
 
 
- sfr DISPDATA = 0x90;                //ÏÔʾ8λÊý¾Ý×ÜÏß
 
 
- typedef struct                        //¶¨Òå´æ´¢Ã¿ÈÕʱ¼äµÄ½á¹¹
 
- {
 
-         uchar hour, min, sec;
 
- }timestruct;
 
 
- bit set_mode         = 0;                //½øÈëÉèÖÃģʽʱÖÃλ
 
- bit disp_updata = 0;        //ÐèҪˢÐÂÏÔʾʱÖÃλ
 
 
- uchar set_mode_to           = 0;        //Ϊÿ´Î°´¼ü²Ù×÷µÄʱ¼ä¼ä¸ô¼ÆÊ±
 
- uchar switch_debounce = 0;        //°´¼üÌø¶¯Éè¼Æ
 
- uchar cur_field           = HOME;        //ÉèÖÃģʽµÄµ±Ç°Î»ÖÃÑ¡Ôñ
 
 
- timestruct curtime;                //´æ·Åµ±Ç°µÄʱ¼ä
 
- timestruct timeholder;        //´æ·ÅÏÔʾʱ¼ä
 
 
- uchar code fieldpos[3] = {
 
-                                                         DISP_LINE2 | 0x01,
 
-                                                         DISP_LINE2 | 0x04,
 
-                                                         DISP_LINE2 | 0x07,
 
- };
 
 
- #define T_HOURT        16
 
- #define T_HOUR  17
 
- #define T_MINT         19
 
- #define T_MIN        20
 
- #define T_SECT  22
 
- #define T_SEC   23
 
 
- char code bcdmap[60][2] = {
 
-         "00","01","02","03","04","05","06","07","08","09",
 
-         "10","11","12","13","14","15","16","17","18","19",
 
-         "20","21","22","23","24","25","26","27","28","29",
 
-         "30","31","32","33","34","35","36","37","38","39",
 
-         "40","41","42","43","44","45","46","47","48","49",
 
-         "50","51","52","53","54","55","56","57","58","59",
 
- };
 
 
- //º¯ÊýÉùÃ÷
 
- void disp_cmd(uchar);
 
- void disp_init(void);
 
- uchar disp_read(void);
 
- void disp_time(void);
 
- void disp_write(uchar);
 
- void incr_field(void);
 
- void second_tick(void);
 
- void set_cursor(bit, uchar);
 
 
- /********************************/
 
- //¹¦ÄÜ£ºÖ÷º¯Êý
 
- //ÃèÊö£º³ÌÐòÈë¿Úº¯Êý£¬³õʼ»¯8051£¬¿ªÖжϣ¬½øÈë¿ÕÏÐģʽ¡£Ã¿´ÎÖжÏÖ®ºó²éѯ±ê־룬ÊÇ·ñË¢ÐÂÏÔʾ
 
- //²ÎÊý£ºÎÞ
 
- //·µ»Ø£ºÎÞ
 
- /********************************/
 
 
- void main(void)
 
- {
 
-         disp_init();                        //ÏÔʾ³õʼ»¯
 
-         TMOD = 0x11;                        //ÉèÖö¨Ê±Æ÷ģʽ£¬T0,T1 16λ²»¿ÉÖØ×°Ä£Ê½
 
-         TCON = 0x15;
 
-         IE          = 0x82;                        //ÔÊÐíT0ÖжÏ
 
-         while(1)
 
-         {
 
-                 if(disp_updata)
 
-                 {
 
-                         disp_time();        //ÏÔʾÐÂʱ¼ä
 
-                 }
 
-                 PCON = 0x01;
 
-         }
 
- }
 
 
- /********************************/
 
- //¹¦ÄÜ£ºdisp_cmd
 
- //ÃèÊö£ºÏòlcdÇý¶¯Æ÷дÈëÃüÁ²¢µÈ´ýÃüÁî±»Ö´ÐÐ
 
- //²ÎÊý£ºÃüÁî
 
- //·µ»Ø£ºÎÞ
 
- /********************************/
 
- void disp_cmd(uchar cmd)
 
- {
 
-         DISPDATA = cmd;                        //Ëø×¡ÃüÁî
 
-         REGSEL = 0;                                //Ñ¡ÔñÃüÁî¼Ä´æÆ÷
 
-         RDWR = 0;                                //Ñ¡Ôñдģʽ
 
-         ENABLE = 1;
 
-         ENABLE = 0;
 
-         TH1 = 0;                                //¶¨Ê±85ms
 
-         TL1 = 0;
 
-         TF1 = 0;
 
-         TR1 = 1;
 
-         while(!TF1 && disp_read() & DISP_BUSY);        //µÈ´ýÃüÁî±»Ö´ÐÐ
 
-         TR1 = 0;
 
- }
 
 
- /********************************/
 
- //¹¦ÄÜ£ºdisp_init
 
- //ÃèÊö£º³õʼ»¯ÏÔʾ
 
- //²ÎÊý£ºÎÞ
 
- //·µ»Ø£ºÎÞ
 
- /********************************/
 
- void disp_init(void)
 
- {
 
-         TH1 = 0;
 
-         TL1 = 0;
 
-         TF1 = 0;
 
-         TR1 = 1;
 
-         while(!TF1 && disp_read() & DISP_BUSY);
 
-         TR1 = 0;
 
-         disp_cmd(DISP_FUNC);                        //ÉèÖÃÏÔʾ¸ñʽ
 
-         disp_cmd(DISP_ENTRY);                        //ÿÊäÈëÒ»¸ö×Ö·û£¬ÏÔʾµØÖ·¼Ó1
 
-         disp_cmd(DISP_CNTL | DISP_ON);        //´ò¿ªÏÔʾ£¬¹Ø±Õ¹â±ê
 
-         disp_cmd(DISP_CLEAR);                        //Çå³ýÏÔʾ
 
- }
 
 
- /********************************/
 
- //¹¦ÄÜ£ºdisp_read
 
- //ÃèÊö£º¶ÁÏÔʾ״̬¼Ä´æÆ÷
 
- //²ÎÊý£ºÎÞ
 
- //·µ»Ø£º´Ó״̬¼Ä´æÆ÷ÖжÁ»ØµÄÊý¾Ý
 
- /********************************/
 
- uchar disp_read(void)
 
- {
 
-         uchar value;
 
-         DISPDATA = 0xFF;
 
-         REGSEL = 0;                                //Ñ¡ÔñÃüÁî¼Ä´æÆ÷
 
-         RDWR = 1;                                //Ñ¡Ôñ¶Áģʽ
 
-         ENABLE = 1;                                //ʹÄÜLCDÊä³ö
 
-         value = DISPDATA;                //¶ÁÊý¾Ý
 
-         ENABLE = 0;
 
-         return (value);
 
- }
 
 
- /********************************/
 
- //¹¦ÄÜ£ºdisp_time
 
- //ÃèÊö£ºÈ¡ÏÔʾÊý¾Ý½øÐиñʽ»¯
 
- //²ÎÊý£ºÎÞ
 
- //·µ»Ø£ºÎÞ
 
- /********************************/
 
- void disp_time(void)
 
- {
 
-         static char time_str[32] = "TIME OF DAY IS:XX:XX:XX";
 
-         uchar i;
 
-         time_str[T_HOURT] = bcdmap[timeholder.hour][0];
 
-         time_str[T_HOUR]  = bcdmap[timeholder.hour][1];
 
-         time_str[T_MINT]  = bcdmap[timeholder.min][0];
 
-         time_str[T_MIN]   = bcdmap[timeholder.min][1];
 
-         time_str[T_SECT]  = bcdmap[timeholder.sec][0];
 
-         time_str[T_SEC]   = bcdmap[timeholder.sec][1];
 
-         putchar(0xFF);
 
-         for(i = 0; i < 32; i++)
 
-         {
 
-                 putchar(time_str[i]);
 
-         }
 
-         disp_updata = 0;
 
- }
 
 
- /********************************/
 
- //¹¦ÄÜ£ºdisp_write
 
- //ÃèÊö£ºÐ´ÈëÒ»¸ö×Ö½ÚÊý¾Ý
 
- //²ÎÊý£ºÒªÐ´ÈëµÄ×Ö½Ú
 
- //·µ»Ø£ºÎÞ
 
- /********************************/
 
- void disp_write(uchar value)
 
- {
 
-         DISPDATA = value;
 
-         REGSEL = 1;
 
-         RDWR = 0;
 
-         ENABLE = 1;
 
-         ENABLE = 0;
 
- }
 
 
- /********************************/
 
- //¹¦ÄÜ£ºincr_field
 
- //ÃèÊö£ºÔö¼ÓÊýÖµ
 
- //²ÎÊý£ºÎÞ
 
- //·µ»Ø£ºÎÞ
 
- /********************************/
 
- void incr_field(void)
 
- {
 
-         if(cur_field == SEC)
 
-         {
 
-                 curtime.sec++;
 
-                 if(curtime.sec > 59)
 
-                         curtime.sec = 0;
 
-         }
 
-         if(cur_field == MIN)
 
-         {
 
-                 curtime.min++;
 
-                 if(curtime.min > 59)
 
-                         curtime.min = 0;
 
-         }
 
-         if(cur_field == HOUR)
 
-         {
 
-                 curtime.hour++;
 
-                 if(curtime.hour > 23)
 
-                         curtime.hour = 0;
 
-         }
 
- }
 
 
- /********************************/
 
- //¹¦ÄÜ£ºputchar
 
- //ÃèÊö£ºÌæ´ú±ê×¼putcharº¯Êý£¬Êä³ö×Ö·û
 
- //²ÎÊý£ºÒªÏÔʾµÄ×Ö·û
 
- //·µ»Ø£º¸Õ¸Õ±»Ð´µÄ×Ö·û
 
- /********************************/
 
- char putchar(char c)
 
- {
 
-         static uchar flag = 0;
 
-         if(!flag || c == 255)
 
-         {
 
-                 disp_cmd(DISP_HOME);
 
-                 flag = 0;
 
-                 if(c == 255)
 
-                         return c;
 
-         }
 
-         if(flag == 16)
 
-                 disp_cmd(DISP_POS | DISP_LINE2);
 
-         disp_write(c);
 
-         while(disp_read() & DISP_BUSY);
 
-         flag++;
 
-         if(flag >= 32)
 
-                 flag = 0;
 
-         return c;
 
- }
 
 
- /********************************/
 
- //¹¦ÄÜ£ºsecond_tick
 
- //ÃèÊö£ºÃ¿ÃëÖÓÖ´ÐÐÒ»´Îº¯Êý¹¦ÄÜ£¬Ê±¼ä¸üÐÂ
 
- //²ÎÊý£ºÎÞ
 
- //·µ»Ø£ºÎÞ
 
- /********************************/
 
- void second_tick(void)
 
- {
 
-         curtime.sec++;                                        //ÃëÖÓ¼Ó1
 
-         if(curtime.sec > 59)                        //¼ì²âÊÇ·ñ³¬³ö·¶Î§
 
-         {
 
-                 curtime.sec = 0;
 
-                 curtime.min++;                                //·ÖÖÓ¼Ó1
 
-                 if(curtime.min > 59)                //¼ì²âÊÇ·ñ³¬³ö·¶Î§
 
-                 {
 
-                         curtime.min = 0;        
 
-                         curtime.hour++;                        //СʱÊý¼Ó1
 
-                         if(curtime.hour > 23)        //¼ì²âÊÇ·ñ³¬³ö·¶Î§
 
-                                 curtime.hour = 0;
 
-                 }
 
-         }
 
-         if(!disp_updata)                                //È·ÐÅtimeholderûÓб»ÏÔʾ
 
-         {
 
-                 timeholder = curtime;                //×°ÈëÐÂʱ¼ä
 
-                 disp_updata = 1;                        //¸üÐÂÏÔʾ
 
-         }
 
- }
 
 
- /********************************/
 
- //¹¦ÄÜ£ºset_cursor
 
- //ÃèÊö£ºÏÔʾ»ò¹Ø±Õ¹â±ê£¬²¢°Ñ¹â±êÒÆµ½Ìض¨µÄλÖÃ
 
- //²ÎÊý£ºnew_mode 룬Òþ²Ø¹â±êʱÖÃλ
 
- //                field          ÏÔʾ¹â±êµÄλÖÃ
 
- //·µ»Ø£ºÎÞ
 
- /********************************/
 
- void set_cursor(bit new_mode, uchar field)
 
- {
 
-         uchar mask;
 
-         mask = DISP_CNTL | DISP_ON;
 
-         if(new_mode)
 
-                 mask |= DISP_CURSOR;
 
-         disp_cmd(mask);
 
-         if(field == HOME)
 
-                 mask = DISP_HOME;
 
-         else
 
-                 mask = DISP_POS | fieldpos[field - 1];
 
-         disp_cmd(mask);
 
- }
 
 
- /********************************/
 
- //¹¦ÄÜ£ºsystem_tick
 
- //ÃèÊö£º¶¨Ê±Æ÷0µÄÖжϷþÎñ³ÌÐò£¬ÃÃ50msÖØ×°Ò»´Î¶¨Ê±Æ÷
 
- //²ÎÊý£ºÎÞ
 
- //·µ»Ø£ºÎÞ
 
- /********************************/
 
- void system_tick(void) interrupt 1
 
- {
 
-         static uchar second_cnt = 20;
 
-         TR0 = 0;
 
-         TH0 = RELOAD_HIGH;                        //Éè¶¨ÖØ×°Öµ
 
-         TL0 = RELOAD_LOW;
 
-         TR0 = 1;                                        //¿ªÊ¼¶¨Ê±
 
-         if(switch_debounce)                        //°´¼ü¶¶¶¯
 
-                 switch_debounce--;
 
-         if(!switch_debounce)
 
-         {                                        
 
-                 if(!SET)                                                        //Èç¹ûÉèÖð´¼ü±»°´ÏÂ
 
-                 {
 
-                         switch_debounce = DB_VAL;                //ÉèÖÃÏû¶¶Ê±¼ä
 
-                         if(!set_mode && !disp_updata)        //Èç¹û²»ÊÇÉèÖÃģʽ
 
-                         {
 
-                                 set_mode = 1;                                //½øÈëÉèÖÃģʽ
 
-                                 set_mode_to = TIMEOUT;                //ÉèÖÿÕÏÐʱ¼ä
 
-                                 cur_field = HOUR;                        //Ñ¡Ôñ¹â±êÆðʼλÖÃ
 
-                                 set_cursor(ON, HOUR);                //ʹÄܹâ±ê
 
-                         }
 
-                         else
 
-                         {
 
-                                 cur_field++;                                //¹â±êλÖÃǰ½ø
 
-                                 if(cur_field > SEC)                        //¹â±êÊÇ·ñ³¬³ö·¶Î§
 
-                                 {
 
-                                         set_mode = 0;                        //Í˳öÉèÖÃģʽ
 
-                                         set_mode_to = 0;
 
-                                         set_cursor(OFF, HOME);        //½ûÄܹâ±ê
 
-                                 }
 
-                                 else
 
-                                 {
 
-                                         set_cursor(ON, cur_field);        //¹â±êÒÆµ½ÏÂÒ»¸öλÖÃ
 
-                                         set_mode_to = TIMEOUT;
 
-                                 }
 
-                         }
 
-                 }
 
-                 if(set_mode && !SELECT)                                //Èç¹û°´ÏÂÑ¡Ôñ°´Å¥
 
-                 {
 
-                         set_mode_to = TIMEOUT;
 
-                         incr_field();                                        //ËùÑ¡Ôñ´¦ÊýÖµÔö¼Ó
 
-                         disp_time();                                        //ÏÔʾʱ¼ä
 
-                 }
 
-         }
 
-         if(!set_mode)                        //ÉèÖÃģʽֹͣʱÖÓ
 
-         {
 
-                 second_cnt--;                //¼ÆÊýÖµ¼õ1
 
-                 if(!second_cnt)                //Èç¹û¾¹ý1Ãë
 
-                 {
 
-                         second_cnt = 20;//ÉèÖüÆÊýÖµ
 
-                         second_tick();
 
-                 }
 
-         }
 
- }