;从8563读出时,分,秒数据,数码管显示
SDA_8563 BIT P0.7 ;时钟芯片的数据线
SCL BIT P0.3 ;164的时钟线
SDA BIT P0.2 ;164的数据线
LED0 EQU 40H ;保存秒个位数据
LED1 EQU 41H ;保存秒十位数据
LED2 EQU 42H ;保存分个位数据
LED3 EQU 43H ;保存分十位数据
LED4 EQU 44H ;保存时个位数据
LED5 EQU 45H ;保存时十位数据
TDATE EQU 46H ;时间缓存
S EQU 47H
MIN EQU 48H
HOU EQU 49H
SUBA EQU 4AH
ORG 0000H
AJMP MAIN
ORG 0100H
;*********主程序***********
MAIN:
ACALL SEND8563 ;写时钟,初初始化时钟为12点0分0秒
LOOP:
ACALL RCV8563 ;读时钟数据
ACALL SEP ;数据拆分
ACALL DISPLAY ;调用显示
ACALL DELAY ;调用延时
AJMP LOOP
;*********主程序结束***********
;**********初始化时间写进8563子程序**************
SEND8563:
MOV S,#00H ;初始化时间
MOV MIN,#00H
MOV HOU,#12H
MOV SUBA,#02H ; 取读秒时间字节地址
MOV TDATE,S ;秒数据
ACALL WRITE_8563 ;把数据读人8563
MOV SUBA,#03H ;取读分时间字节地址
MOV TDATE,MIN
ACALL WRITE_8563
MOV SUBA,#04H ;取读时时间字节地址
MOV TDATE,HOU
ACALL WRITE_8563
RET
;**********初始化时间写进8563子程序 结束**************
;**********写8563子程序************
WRITE_8563:
ACALL START ;发送IC总线起始条件启动PC8563
MOV A,#0A2H ;取器件地址向8563发出写的指令
ACALL WRITE_BYTE ;写进PCF8563器件总线地址
MOV A,SUBA ;取读时间字节地址
ACALL WRITE_BYTE ;写进时间字节地址
MOV A,TDATE ;将所要写入的数据写入
ACALL WRITE_BYTE ;写进时间
ACALL STOP ;发送IC总线停止条件
RET
;**********写8563子程序结束***********
;********读8563子程序**************
RCV8563:
ACALL START ;启动总线
MOV A,#0A2H ;写操作器件地址
ACALL WRITE_BYTE ;写入器件地址
MOV A,#02H ;选择单元地址
ACALL WRITE_BYTE ;写入单元地址
ACALL START ;重新启动总线
MOV A,#0A3H ;读操作器件地址
ACALL WRITE_BYTE ;写入器件地址
ACALL READ_BYTE ;读入一个数据:秒
ANL A,#7FH ;屏蔽无效位
MOV S,A ;送秒保存单元
ACALL START ;重新启动总线
MOV A,#0A3H ;读操作器件地址
ACALL WRITE_BYTE ;写入器件地址
ACALL READ_BYTE ;读下个字节数据:分
ANL A,#7FH ;屏蔽无效位
MOV MIN,A ;送分保存单元
ACALL START
MOV A,#0A3H
ACALL WRITE_BYTE
ACALL READ_BYTE ;读下个字节数据:时
ANL A,#3FH ;屏蔽无效位
MOV HOU,A ;送时保存单元
ACALL STOP ;结束总线
RET
;******读8563子程序结束************
;***写一个字节子程序*********
WRITE_BYTE:
MOV R0,#8 ;写进的数据为8位
CLR C ;清进位标志
CLR SCL_8563 ;时钟线钳位为0
DL:
RLC A ;要发送的数据左移,被写进位进人C
MOV SDA_8563,C ;要写进的位送到时钟线
NOP
NOP
NOP
SETB SCL_8563 ; 置时钟线为高,数据写入芯片
NOP
NOP
NOP
CLR SCL_8563 ;钳住总线准备接受下一个数据位
NOP
NOP
NOP
DJNZ R0,DL ;8位没写完继续写
SETB SDA_8563 ;8位发送完后释放数据线准备收应答位
NOP
NOP
NOP
SETB SCL_8563 ;开始接受应答信号
NOP
NOP
NOP
CLR F0 ;预先清发送数据出错标志
JNB SDA_8563,ACKEND ;判断是否接受应答信号正常转ACKEND
SETB F0 ;未受到应答置位错误标志
ACKEND:
NOP
NOP
CLR SCL_8563 ;发送结束钳住总线准备下一步发送或接受数据或进行其他处理
RET
;***写一个字节子程序结束*********
;******读一个字节子程序************
READ_BYTE:
MOV R0,#8
SETB SDA_8563 ;置数据线为输入方式
CLR A
NOP
NOP
NOP
READ:
CLR SCL_8563 ;置时钟线为低,准备接受数据
nop
nop
nop
nop
nop
nop
SETB SCL_8563 ;置时钟线为高使数据线上数据有效
NOP
NOP
NOP
MOV C,SDA_8563 ;接受的数据位放入ACC
RLC A
NOP
NOP
NOP
DJNZ R0,READ ;8位没收完继续接受
NOP
NOP
CLR SCL_8563
nop
nop
RET
;**********写一个字节子程序结束**********
;**********启动总线子程序*********
START:
SETB SDA_8563 ;发送起始条件的数据信号
SETB SCL_8563
NOP
NOP
NOP
CLR SDA_8563 ;发送起始信号
NOP
NOP
NOP
CLR SCL_8563 ;钳住总线
RET
;**********启动总线子程序 结束*********
;**********停止总线子程序***********
STOP:
CLR SCL_8563
NOP
NOP
NOP
CLR SDA_8563 ;发送停止条件的数据信号
NOP
NOP
NOP
SETB SCL_8563 ;发送停止条件的时钟信号
NOP
NOP
NOP
SETB SDA_8563 ;发送IC总线停止信号
NOP
NOP
NOP
CLR SCL_8563
RET
;**********停止总线子程序 结束***********
;******拆分子程序***********
SEP:
MOV A,S ;秒
ANL A,#0FH ;屏蔽高四位,只取低四位
MOV LED0,A ;秒个位存到LED0
MOV A,S ;秒重载
ANL A,#0F0H ;屏蔽底四位,取高四位
SWAP A ;高低字节交换
MOV LED1,A ;秒十位存到LED1
MOV A,MIN
ANL A,#0FH
MOV LED2,A
MOV A,MIN
ANL A,#0F0H
SWAP A
MOV LED3,A
MOV A,HOU
ANL A,#0FH
MOV LED4,A
MOV A,HOU
ANL A,#0F0H
SWAP A
MOV LED5,A
RET
;******拆分子程序 结束***********
;******显示子程序***********
DISPLAY:
MOV DPTR,#TAB
MOV A,LED0
MOVC A,@A+DPTR
ACALL SHIFT
MOV A,LED1
MOVC A,@A+DPTR
ACALL SHIFT
MOV A,#0FFH
ACALL SHIFT
MOV A,LED2
MOVC A,@A+DPTR
ACALL SHIFT
MOV A,LED3
MOVC A,@A+DPTR
ACALL SHIFT
MOV A,#0FFH
ACALL SHIFT
MOV A,LED4
MOVC A,@A+DPTR
ACALL SHIFT
MOV A,LED5
MOVC A,@A+DPTR
ACALL SHIFT
RET
;******显示子程序 结束***********
;*********************
SHIFT:
MOV R0,#8
CLR C
DLL:
CLR SCL
RLC A
MOV SDA,C
SETB SCL
DJNZ R0,DLL
RET
;********************
;*********延时子程序********
DELAY:
MOV R1,#0FFH
DEL1:
MOV R2,#0FFH
DEL2:
DJNZ R2,DEL2
DJNZ R1,DEL1
RET
;*********延时子程序 结束********
;*************
tab:
DB 11h,0d7h,32h, 92h,0d4h,98h,18h,0d3h,10h,090h,0FFH
;******************
END