本人用AT89C51和DS1302 抄別人的軟件 制作了個時鐘,時鐘倒是可以正常走時,只是有個問題,斷電后重新通電,時間不能顯示當時時間,會回到初始化時間,時間需要重新調整,感覺是程序中少了實時時間處理這個代碼,DS1302已經安裝了電池,本人單片機不經常使用,自學了匯編后只會匯編,C只能看個大概,哪個高手幫幫忙看看這程序需要如何改才可以時時顯示時間,只要顯示 秒分時 時間就可以了,其他功能不需要,謝謝!
T_CLK Bit P1.6 ;實時時鐘時鐘線引腳
T_IO Bit P1.5 ;實時時鐘數據線引腳
T_RST Bit P1.4 ;實時時鐘復位線引腳
D6 BIT P2.0 ;小時十位數碼管
D5 BIT P2.1 ;小時個位數碼管
D4 BIT P2.2 ;分鐘十位數碼管
D3 BIT P2.3 ;分鐘個位數碼管
D2 BIT P2.4 ;秒十位數碼管
D1 BIT P2.5 ;秒個位數碼管
D_OUT EQU P0 ;數碼管段位連接端
DOT BIT 20H.0
POT BIT 20H.1
second EQU 60h ;秒的緩沖區
minute EQU 61h ;分的緩沖區
hour EQU 62h ;小時的緩沖區
DAY EQU 63H
MONTH EQU 64H
WEEK EQU 65H
YEARL EQU 66H
;**************************************************************
;**************************************************************
ORG 00H
JMP START
ORG 0BH
JMP TIM0
ORG 30H
START: MOV SP,#70H
MOV SECOND,#36H
MOV MINUTE,#49H
MOV HOUR,#08H
MOV P2,#0FFH
MOV DPTR,#TAB
lcall SETDS1302 ;DS1302初始時間
lcall GET1302 ;DS1302讀取時間
lcall DSP ;顯示時間子程序
MOV R1,#5FH
mov r4,#00
mov ie,#82h
mov tmod,#01h
mov th0,#(65536-3000)/256
mov tl0,#(65536-3000)mod 256
setb tr0
;******************
DIR: NOP
JMP DIR
;******************
TIM0:push acc
push psw
mov th0,#(65536-2000)/256
mov tl0,#(65536-2000)mod 256
lcall DSP ;顯示時間子程序
lp2: djnz r3,lp1 ;未到1 S繼續循環
mov r3,#20
cpl dot
CJNE R1,#5FH,LP1
lcall GET1302 ;每過1s從DS1302讀取一次時間
lp1:pop psw
pop acc
reti
;****************************************************
;顯示時間掃描子程序
DSP: CJNE R1,#60H,SS
。。。。。。。此次有代碼省略
DSP3: RET
;---------------------------------------------------------------------------------------------------
;設置DS1302初始時間,并啟動計時
SETDS1302:
CLR T_RST
nop
CLR T_CLK
nop
SETB T_RST
nop
MOV B,#8EH ;寫控制命令字
LCALL INPUTBYTE
MOV B,#00H ;寫保護關閉
LCALL INPUTBYTE
SETB T_CLK
nop
CLR T_RST
MOV R0,#SECOND ;內存中的時間首地址
MOV R2,#80H ;DS1302中的時間首地址
MOV R7,#7 ;字節數
SETLOOP:
CLR T_RST
nop
CLR T_CLK
nop
SETB T_RST
nop
MOV B,R2 ;寫命令字
LCALL INPUTBYTE
MOV A,@R0 ;設置時間
MOV B,A
LCALL INPUTBYTE
INC R0
INC R2
INC R2
SETB T_CLK
nop
CLR T_RST
nop
DJNZ R7,SETLOOP
CLR T_RST
nop
CLR T_CLK
nop
SETB T_RST
nop
MOV B,#8EH
LCALL INPUTBYTE
MOV B,#80H ;開寫保護
LCALL INPUTBYTE
SETB T_CLK
nop
CLR T_RST
nop
RET
;---------------------------------------------------------------------------------------------------
;從DS1302讀取時間
GET1302:
MOV R0,#SECOND
MOV R2,#81H ;DS1302中讀時間的首地址
MOV R7,#7
GETLOOP:
CLR T_RST
nop
CLR T_CLK
nop
SETB T_RST
nop
MOV B,R2
LCALL INPUTBYTE ;寫命令字
LCALL OUTPUTBYTE ;讀時間
MOV @R0,A ;將從DS1302中讀取的時間從內存中保存
INC R0 ;修改地址指針
INC R2
INC R2
SETB T_CLK
nop
CLR T_RST
nop
DJNZ R7,GETLOOP
RET
;---------------------------------------------------------------------------------------------------
;向DS1302寫一個字節
INPUTBYTE:
MOV R4,#8
INPUTLOOP:
MOV A,B
RRC A
MOV B,A
MOV T_IO,C
SETB T_CLK
NOP
NOP
NOP
CLR T_CLK
DJNZ R4,INPUTLOOP
RET
;---------------------------------------------------------------------------------------------------
;從DS1302讀一個字節
OUTPUTBYTE:
clr a
clr c
MOV R4,#8
OUTPUTLOOP:
NOP
NOP
MOV C,T_IO
RRC A
SETB T_CLK
NOP
NOP
NOP
CLR T_CLK
DJNZ R4,OUTPUTLOOP
RET
DELAY: MOV R6,#10
DD1: MOV R7,#248
DJNZ R7,$
DJNZ R6,DD1
RET
DLAY:MOV R5,#100
DJNZ R5,$
RET
TAB: DB 03H,9FH,25H,0DH,99H,49H,41H,1FH,01H,09H;0123456789
end
|