📄 ds1302.txt
字号:
串行日历/时钟芯片DS1302的应用子程序
CODE:
;范例99
; AVR与DS1302接口为:PC0--SCLK,PC1--DATA,PC2--/RST。请参看本范例之附图。
; 结构与运作特点如下:
;(1)采用标准频率晶体(32768HZ),便于调整(可加电容补偿),可对PC0/PC1/PC2加提拉电阻。
;(2)DS1302只有8只脚,小巧精悍,耗电省,抗干扰.便于与单片机接口,以串行方式按位读写数据.
;(3)以备用电池供电保存数据,断电后自动执行写保护,故可靠性高。上电后须用指令解除写保护。
;(4)片内除8个时钟日历单元外还有31个RAM单元,可作为系统断电保护数据存储单元
;(5)可以并发(BURST,即连续)方式读写8个时钟日历单元(秒/分/时/日/月/周/年/年)或读写31个RAM单元,
; 命令如下:
; $BE为以并发方式写8个时钟日历单元,$BF为以并发方式读8个时钟日历单元。
; $FE为以并发方式写31个RAM单元,$FF为以并发方式读31个RAM单元。
;(6)除以并发方式读写外,还可按字节读写,但读写前须先写入命令。
; 读写命令格式为:1 Y A4 A3 A2 A1 A0 X,最高位为1表示命令有效,Y=0,选择读写时间/日期
; Y=1,选择读写片内RAM,A4-A0,片内RAM/时钟单元地址,X=0,选择写操作,X=1,选择读
;操作.
;(7)串行时钟上升沿写入一位数据,下降沿读出一位数据;且读写只有在/RST信号为高时才有效。
; 故要求/RST信号有效前时钟信号应已就绪。
;(8)本程序AVR时钟为4MHZ,若使用其他时钟,重新调整读写延时时间(程序中NOP之个数)
;(9)对RAM并发读写方法可参考并发读写时钟日历子程序进行.
;1)并发(BURST)方式写时钟日历单元(时钟日历数据 秒,分,时,日,月,周,年,年分别在R8--R15,)
WBURST: CLR YH ;
LDI YL,8 ;数据指针,首指秒单元R8
RCALL DEPRV ;解除写保护(写入$8E00)
CBI PORTC,0 ;为上升沿写作准备(SCLK升高)
NOP
NOP
NOP
SBI PORTC,2 ;复位信号变高(SETB RST)
NOP
NOP
NOP
NOP
NOP
NOP
LDI R18,$BE ;BURST(wr.) ADDR.&INSTRUC.(命令$BE)
RCALL WBYTE ;
WLOP: LD R18,Y+ ;r9
RCALL WBYTE ;写入1字节数据
CPI YL,16
BRNE WLOP ;数据都写完?
CBI PORTC,2 ;禁止读写
NOP
NOP
NOP
NOP
CBI PORTC,0
RET
;2)并发(BURST)方式读时钟日历单元(时钟日历数据 秒,分,时,日,月,周,年,
;分别读到R8--R14中)
RBURST: CLR YH ;首指R8
LDI YL,8
SBI DDRC,0 ;SCLK 输出
SBI DDRC,2 ;WR/RD ENABLE 输出
SBI PORTC,0 ;时钟SCLK初始输出为低
NOP
NOP
NOP
SBI PORTC,2 ;复位有效,允许时钟相关沿有效
NOP
NOP
NOP
NOP
NOP
NOP
LDI R18,$BF ;BURST(rd.) ADDR.&INSTRUC.
RCALL WBYTE ;写入并发读命令
RLOP: RCALL RBYTE ;读出一字节时钟/日历数据
ST Y+,R18 ;存储
CPI R28,15
BRNE RLOP ;数据都读完?
CBI PORTC,2 ;禁止读写
NOP
NOP
NOP
NOP
CBI PORTC,0 ;使SCLK变低
RET
;3)解除写保护子程序(对DS1302写入$8E,$00)
DEPRV: SBI DDRC,0 ;SCLK 输出
SBI DDRC,2 ;WR/RD ENABLE 输出
CBI PORTC,0 ;时钟SCLK初始输出为低
NOP
NOP
NOP
SBI PORTC,2 ;复位有效,允许时钟相关沿有效
NOP
NOP
NOP
NOP
NOP
NOP
LDI R18,$8E
RCALL WBYTE
NOP
NOP
CLR R18
RCALL WBYTE ;写入$8E和$00
CBI PORTC,2 ;禁止读写
NOP
NOP
NOP
NOP
CBI PORTC,0
RET
;4)对DS1302秒,分,时单元写入3字节数据
WTIME: CLR YH ;
LDI R17,$80 ;写秒单元命令
LDI YL,8 ;R8(秒)R9(分)R10(时)
LDI R19,3
WCOM: RCALL DEPRV ;解除写保护
WLOP1: CBI PORTC,0 ;时钟SCLK初始输出为低
NOP
NOP
NOP
SBI PORTC,2 ;复位有效,允许时钟相关沿有效
NOP
NOP
NOP
NOP
NOP
NOP
MOV R18,R17
RCALL WBYTE ;写入一字节命令
SUBI R17,$FE ;指向时间下一单元 相当于 r17+2
LD R18,Y+ ;Y地址的数据加载后 地址+1
RCALL WBYTE ;写入时间单元1字节
CBI PORTC,2 ;禁止读写
NOP
NOP
NOP
NOP
CBI PORTC,0
DEC R19
BRNE WLOP1 ;写完规定字节?
RET
;5)写入日期子程序
WDATE: CLR YH ;
LDI YL,11 ;R11(日)R12(月)R13(周)R14(年)
LDI R17,$86 ;写日单元命令
LDI R19,4
RJMP WCOM
;6)读出时间子程序
RTIME: CLR YH ;
LDI R17,$81 ;读秒单元命令
LDI YL,8 ;读出数据送到R8(秒)R9(分)R10(时)
LDI R19,3
RCOM: SBI DDRC,0 ;SCLK 输出
SBI DDRC,2 ;WR/RD ENABLE 输出
RLOP1: CBI PORTC,0 ;时钟SCLK初始输出为低
NOP
NOP
NOP
SBI PORTC,2 ;允许读写
NOP
NOP
NOP
NOP
NOP
NOP
MOV R18,R17
RCALL WBYTE ;写入读命令
SUBI R17,$FE ;指向下一单元地址
RCALL RBYTE ;读出一字节数据
ST Y+,R18
CBI PORTC,2 ;禁止读写
NOP
NOP
NOP
NOP
CBI PORTC,0 ;时钟变低
DEC R19
BRNE RLOP1 ;已读出规定字节?
RET
;7)读出日期子程序
RDATE: CLR YH
LDI YL,11 ;读出数据放入R11(日)R12(月)R13(周)R14(年)
LDI R17,$87 ;读出日单元命令
LDI R19,4
RJMP RCOM
;8)将R18中数据写入DS1302
WBYTE: LDI R16,8 ;8位/字节
SBI DDRC,1 ;PC1为输出
WB1: CBI PORTC,0 ;时钟SCLK初始输出为低
ROR R18 ;一位数据传到进位C
BRCC WB10
SBI PORTC,1
RJMP WB2
WB10: CBI PORTC,1 ;1位数据输出到数据线(DS1302'DATA BUS)
WB2: NOP
NOP
NOP
NOP
SBI PORTC,0 ;上升沿写入一位
DEC R16
BRNE WB1 ;8位数据都写完?
RET
;9)读出DS1302一字节数据在r18中
RBYTE: LDI R16,8 ;8位/字节
CBI DDRC,1 ;PC1输入
RD1: CBI PORTC,0 ;下降沿读出一位数据
NOP
NOP
NOP
NOP
SBI PORTC,1 ;上拉电阻激活
CLC
SBIC PINC,1
SEC ;读出一位数据并-->C
ROR R18 ;组织数据
SBI PORTC,0 ;SCLK升高,为下位读准备
DEC R16
BRNE RD1 ;8位数据都写完?
RET
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -