本人用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
|