以下是我的DS1302汇编程序
;*********************************************************************/
T_RST Bit P3.3 ;实时时钟复位线引脚
T_CLK Bit P3.4 ;实时时钟时钟线引脚
T_IO Bit P3.5 ;实时时钟数据线引脚
SECOND EQU 30H
MINUTE EQU 31H
HOUR EQU 32H
DAY EQU 33H
MONTH EQU 34H
WEEK EQU 35H
YEARL EQU 36H
;*********************************************************************/
ORG 0000H
LJMP START
ORG 0060H
START: ;CLR T_RST
;CLR T_CLK
MOV SP,#60H ;修改堆栈
MOV SECOND,#00H ;初始时间设为12:00:00
MOV MINUTE,#00H
MOV HOUR,#12H
MOV DAY,#01H ;初始日期设为08年1月1日第一周
MOV MONTH,#01H
MOV WEEK,#01H
MOV YEARL,#08H
LCALL SETDS1302
LCALL GET1302
LCALL DISPLAY
MAIN: MOV R3,#25
MOV TMOD,#01H
MOV TH0,#70H ;置定时器初值(定时40ms)
MOV TL0,#00H
SETB TR0 ;启动定时器0
LP1: JBC TF0,LP2 ;查询计数溢出
SJMP LP1 ;未到40 ms继续计数
LP2: MOV TH0,#0B8H ;重新置定时器初值
MOV TL0,#00H
LCALL DISPLAY ;显示
DJNZ R3,LP1 ;未到1 S继续循环
LCALL GET1302 ;每过1s从DS1302读取一次时间
mov r3,#25
SJMP lp1
;---------------------------------------------------------------------------------------------------
;字符显示码表
DIG_CODE:
DB 0C0H,0F9H,0A4H,0B0H,099H,092H,082H,0F8H,080H,090H
;---------------------------------------------------------------------------------------------------
;---------------------------------------------------------------------------------------------------
;数码显示子程序
DISPLAY:
MOV DPTR,#DIG_CODE
;*******************************************
;显示秒
MOV A,SECOND
ANL A,#0FH
MOVC A,@A+DPTR
MOV P2,A
MOV P1,#11011111b
LCALL DIS_DELAY
MOV A,SECOND
SWAP A
ANL A,#07H
MOVC A,@A+DPTR
MOV P2,A
MOV P1,#11101111b
LCALL DIS_DELAY
;*******************************************
;显示分
MOV A,MINUTE
ANL A,#0FH
MOVC A,@A+DPTR
MOV P2,A
MOV P1,#11110111b
LCALL DIS_DELAY
MOV A,MINUTE
SWAP A
ANL A,#07H
MOVC A,@A+DPTR
MOV P2,A
MOV P1,#11111011b
LCALL DIS_DELAY
;*******************************************
;显示小时
MOV A,HOUR
ANL A,#0FH
MOVC A,@A+DPTR
MOV P2,A
MOV P1,#11111101b
LCALL DIS_DELAY
MOV A,HOUR
SWAP A
ANL A,#03H
MOVC A,@A+DPTR
MOV P2,A
MOV P1,#11111110b
LCALL DIS_DELAY
RET
;---------------------------------------------------------------------------------------------------
;---------------------------------------------------------------------------------------------------
;显示延时5ms子程序
DIS_DELAY:
PUSH PSW
MOV R7,#10
D1: MOV R6,#248
D2: DJNZ R6,$
DJNZ R7,D1
POP PSW
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 R1,#80H ;DS1302中的时间首地址
MOV R7,#7 ;字节数
SETLOOP:
CLR T_RST
nop
CLR T_CLK
nop
SETB T_RST
nop
MOV B,R1 ;写命令字
LCALL INPUTBYTE
MOV A,@R0 ;设置时间
MOV B,A
LCALL INPUTBYTE
INC R0
INC R1
INC R1
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 R1,#81H ;DS1302中读时间的首地址
MOV R7,#7
GETLOOP:
CLR T_RST
nop
CLR T_CLK
nop
SETB T_RST
nop
MOV B,R1
LCALL INPUTBYTE ;写命令字
LCALL OUTPUTBYTE ;读时间
MOV @R0,A ;将从DS1302中读取的时间从内存中保存
INC R0 ;修改地址指针
INC R1
INC R1
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
end
用户258758 2010-3-20 13:26
用户1044479 2007-12-4 08:09
用户1113192 2007-12-3 20:14
用户1113192 2007-12-3 20:12
看了你的DS1302就想起当年的处女作,T6963C了。N年前的事了。
楼主加油!!
用户114532 2007-12-3 16:58
不错~~顶!!