DS1302 是美国DALLAS公司推出的一种高性能、低功耗、带RAM的实时时钟电路,它可以对年、月、日、周日、时、分、秒进行计时,具有闰年补偿功能,工作电压为2.5V~5.5V。采用三线接口与CPU进行同步通信,并可采用突发方式一次传送多个字节的时钟信号或RAM数据。DS1302内部有一个31×8的用于临时性存放数据的RAM寄存器。DS1302是DS1202的升级产品,与DS1202兼容,但增加了主电源/后背电源双电源引脚,同时提供了对后背电源进行涓细电流充电的能力。
ds1302程序
;=======================================================
; funcTIon: 发送数据程序
; input: command---准备发送命令
; r0--------原数据首地址
; r7-------数据字节计数
; output: ---------
; usage: a,
; r0
; r2--------数据位计数器
; r7
;=========================================================
ds_send_byte:
clr DS_RST ;复位引脚为低电平,所有数据传送终止
nop
clr DS_CLK ;清时钟总线
nop
setb DS_RST ;复位引脚为高电平,逻辑控制有效
nop
mov a, command ;准备发送命令字节
mov r2, #08h ;传送位数为8
ds_byte0:
rrc a ;将最低位传送给进位位C
mov DS_IO, C ;位传送至数据总线
nop
setb DS_CLK ;时钟上升沿,发送数据有效
nop
clr DS_CLK ;清时钟总线
djnz r2, ds_byte0 ;位传送未完毕则继续
nop
ds_byte1:
mov a, @r0 ;准备发送数据
mov r2, #08h ;传送数据,过程与传送命令相同
ds_byte2:
rrc a
mov DS_IO, c
nop
setb DS_CLK
nop
clr DS_CLK
djnz r2, ds_byte2
inc r0 ;发送数据的内存地址加1
djnz r7, ds_byte1 ;字节传送未完毕则继续
nop
clr DS_RST ;逻辑操作完毕,清DS_RST
ret
;======================================================
; funcTIon: 接收数据程序
; input: command---准备发送命令
; r1--------即目标数
; r7--------数据字节计数器
; output: ---------
; usage: a,
; r1
; r2--------数据位计数器
; r7
;===================================================
ds_receive_byte:
clr DS_RST ;复位引脚位低电平,所有数据传送终止
nop
clr DS_CLK ;清时钟总线
nop
setb DS_RST ;复位引脚为高电平,逻辑控制有效
mov a, command ;准备发送命令字节
mov r2, #08h ;传送位数为8
ds_r_byte0:
rrc a ;将最低位传送给进位位c
mov DS_IO, c ;位传送给数据总线
nop
setb DS_CLK ;时钟上升沿,发送数据有效
nop
clr DS_CLK ;清时钟总线
djnz r2, ds_r_byte0 ;位传送未完毕则继续
nop
ds_r_byte1:
;准备接收数据
clr a ;清累加器
clr c ;清进位位c
mov r2, #08h ;接收位数为8
ds_r_byte2:
nop
mov c, DS_IO ;数据总线上的数据传送给C
rrc a ;从最低位接收数据
setb DS_CLK ;时钟总线置高
nop
clr DS_CLK ;时钟下降沿接收数据有效
djnz r2, ds_r_byte2 ;位接收未完毕则继续
mov @r1, a ;接收到的完整数据字节放入接收内存缓冲区
inc r1 ;接收数据的内存地址加1
djnz r7, ds_r_byte1 ;字节接收未完毕则继续
nop
clr DS_RST ;逻辑操作完毕,清DS_RST
ret
;======================================================
; funcTIon: write 多字节写入
; input: command---准备发送命令
; r0--------原数据首地址
; r7--------数据字节数也是多字节写入模式
; output: ---------
; usage: r0,r7,command,dsdat
;=========================================================
write_mulTIbyte:
mov command, #0beh ;命令字节为beh
mov r7, #08h ;多字节写入模式(此模式为8个)
mov r0, #dsdat ;数据地址覆给r0
mov dsdat, #00h ;秒单元内容为00h
mov dsdat+1, #00h ;分单元内容为00h
mov dsdat+2, #00h ;时单元内容为12h
mov dsdat+3, #15 ;日期单元内容为15h
mov dsdat+4, #07h ;月单元内容为07h
mov dsdat+5, #04h ;星期单元内容为04h
mov dsdat+6, #04h ;年单元内容为04h
mov dsdat+7, #00h ;写保护单元内容为00h
lcall ds_send_byte ;调用写入数据子程序
ret
;=================================================
; function: read 多字节读出
; input: command---准备发送命令
; r7---------在这里为读出的数据字节数为3个
; ---------
; output: ---------
; usage: a,r7
; r1-------目标数据地址
; rcvdat-------所接收的数据地址
;========================================================
read_multibyte:
mov command, #0bfh ;命令字节为BFh
mov r7, #3h ;多字节读出模式(由于只需要时,分,秒所以只需读出3个
mov r1, #rcvdat ;数据地址覆给r1
lcall ds_receive_byte ;调用读出数据子程?
mov r1, #rcvdat ;数据地址覆给r1
mov a, @r1 ;将 R1里的数据送给a
lcall zip_to_unzip ;调用解压即拆字节
mov CLK_SecL, b ;将低位送给秒低位
mov CLK_SecH, a ;将高位送给秒高位
inc r1
mov a, @r1 ;将 R1里的数据送给a
lcall zip_to_unzip
mov CLK_MinL, b
mov CLK_MinH, a
inc r1
mov a, @r1 ;将 R1里的数据送给a
lcall zip_to_unzip
mov CLK_HourL, b
mov CLK_HourH, a
ret
;=====================================================
; function: clk_enable;启动时钟开始
; input: command---准备发送命令
; r7--------数据字节数也是多字节写入模式
; ---------
; output: ---------
; usage: r3,r7
;=======================================================
clk_enable:
mov command, #80h ;命令字节为80h,启动时钟开始
mov r7, #8h ;多字节传送模式
mov r3, #dsdat ;数据地址覆给r3
mov dsdat, #00h ;数据内容为0(振荡器工作允许)
lcall ds_send_byte ;调用写入数据子程序
ret
;=====================================================
; function: write_enable;允许写程序
; input: command---准备发送命令
; r7--------数据字节数也是多字节写入模式?
;
---------
; output: ---------
; usage: r4,r7
;========================================
write_enable:
mov command, #8eh ;命令字节为8e允许写命令
mov r7, #8h
mov r4, #dsdat ;数据地址覆给r4
mov dsdat, #00h ;数据内容为0(写入允许)
lcall ds_send_byte ;调用写入数据子程序
ret
;======================================================
; function: charge_set;充电子程序
; input: command---准备发送命令
; r7--------数据字节数也是多字节写入模式?
;
r0--------原数据首地址
; output: ---------
; usage: r0,r7
;==========================================================
charge_set:
mov command, #90h ;充电命令字为90h
mov r7, #1 ;单字节传送
mov r0, #dsdat
mov dsdat, #0a5h ;数据内容为5ah(允许充电)
lcall ds_send_byte ;调用写入数据子程序
ret