START:
ACALL SETTIME ;设置初始时间 LOOP: ACALL GETTIME ;循环读取当前时间 AJMP LOOP;
SETTIME: MOV DPTR,#7D0AH ;DS12C887的A寄存器 MOV A,#20H MOVX @DPTR,A ;打开DS12C887的内部晶振并使RTC(实时时钟)记录时间 INC DPTR ;DS12C887的B寄存器 MOV A,#08H MOVX @DPTR,A ;设十进制BCD码,24小时制,不定时 MOV DPTR,#7D0DH ;DS12C887的D寄存器 MOVX A,@DPTR ;如果D寄存器的第7位为0,表示电池耗尽 JNB ACC.7,ERROR MOV DPTR,#7D00H ;DS12C887的秒单元 MOV A,#00H MOVX @DPTR,A ;写入秒 MOV DPTR,#7D02H ;DS12C887分单元 MOV A,#21H MOVX @DPTR,A ;写入分 MOV DPTR,#7D04H ;DS12C887时单元 MOV A,#03H MOVX @DPTR,A ;写入时 MOV DPTR,#7D06H ;DS12C887星期单元 MOV A,#03H MOVX @DPTR,A ;写入星期 MOV DPTR,#7D07H ;DS12C887日单元 MOV A,#20H MOVX @DPTR,A ;写入日 MOV DPTR,#7D08H ;DS12C887月单元 MOV A,#07H MOVX @DPTR,A ;写入月 MOV DPTR,#7D09H ;DS12C887年单元 MOV A,#05H MOVX @DPTR,A ;写入年时间 ERROR: RET
GETTIME:
MOV DPTR,#7D0AH MOVX A,@DPTR
JB ACC.7,GETTIME ;REGISTER A的UIP位=0时才可以读数据
MOV DPTR,#7D00H
MOVX A,@DPTR
MOV R2,A ;SECONDS ACALL DISPLAY
MOV DPTR,#7D02H MOVX A,@DPTR MOV R1,A
ACALL DISPLAY ;MINUTES
MOV DPTR,#7D04H MOVX A,@DPTR
MOV R0,A ;HOURS ACALL DISPLAY
ACALL DELAY RET DISPLAY:
MOV DPTR,#TAB MOV SCON,#00H MOV R3,A ANL A,#0FH
MOVC A,@A+DPTR MOV SBUF,A JNB TI,$ CLR TI MOV A,R3 SWAP A ANL A,#0FH
MOVC A,@A+DPTR MOV SBUF,A JNB TI,$ CLR TI RET DELAY:
MOV R4,#0FH DE1:MOV R5,#0FFH DJNZ R5,$ DJNZ R4,DE1 RET
TAB: DB 03H,9FH,25H,0DH,99H,49H,41H,1FH,01H,09H,11H,0C1H,63H,85H,61H,71H END
C语言源程序:
#include \#include \
#define DSA XBYTE[0x7F0A] //12c887寄存器A地址 #define DSB XBYTE[0x7F0B] //B地址 #define DSD XBYTE[0x7F0D] //D地址 #define DS_H XBYTE[0x7F04] //时地址 #define DS_M XBYTE[0x7F02] //分地址 #define DS_S XBYTE[0x7F00] //秒地址 #define DS_W XBYTE[0x7F06] //星期地址 #define DS_D XBYTE[0x7F07] //日地址 #define DS_Mo XBYTE[0x7F08] //月地址 #define DS_Y XBYTE[0x7F09] //年地址
code unsigned char LED_code_tab[]={ /* 显示段笔划 abcdefgh; 0=亮 */ 0x03,0x9f,0x25,0x0d,0x99,0x49,0x41,0x1f, /* 0,1,2,3,4,5,6,7 */
0x01,0x09,0x11,0xc1,0x63,0x85,0x61,0x71,0xff /* 8,9,A,b,C,d,E,F,全灭 */ };
sbit Set=P1^0; //设置时间标志位 sbit Set_h=P1^1; //设置小时 sbit Set_m=P1^2; //设置分钟 sbit Set_s=P1^3; //设置秒钟
code struct time { int Year; //当前时间 年 int Month; //当前时间 月 int Day; //当前时间 日 int Week; //当前时间 星期 int Hour; //当前时间 时 int Minutes; //当前时间 分 int Seconds; //当前时间 秒 int a_Hour; //报警时间 时 int a_Minutes; //报警时间 分 int a_Seconds; //报警时间 秒 };
struct time time_n; //保存当前时间的结构体 struct time time_t; //保存上次调用显示时的时间的结构体
void Init(); //程序初始化函数
void Init12c887(); //初始化12c887的函数 void GetTime(); //获取当前时间的函数 void ShowTime(); //显示当前时间(设置)的函数 void Display(int temp); //显示传入参数的函数 void SetTime(); //用户设置时间函数 void UpDateTime(); //更新12c887中时间的函数(供用户设置时间函数调用)
void Init() //程序初始化函数 { time_n.Seconds=0; time_n.Minutes=0; time_n.Hour=0; time_n.Week=0; time_n.Day=0; time_n.Month=0; time_n.Year=0; time_t=time_n; Set=1; Set_h=1; Set_m=1; Set_s=1; }
void Init12c887() //初始化12c887控制寄存器 { DSA=0x20; //打开DS12C887的内部晶振并使RTC(实时时钟)记录时间 DSB=0x0E; //设二进制计数(汇编语言可用十进制BCD计数),不定时 }
void GetTime() //获得当前时间函数 { char temp2; temp2=0x00; temp2=DSA; if((temp2 & 0x80)!=0x00) //判断寄存器12c887控制寄存器A的最高位是否位0(即是否可以读数) { return; }