#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();
}
}
}