如何自动决定 DS1302 是否需要初始化
针对本论坛供应的 51HEI-5 带有的 DS1302 实验,同时浏览了本实验中朋友们提及的实时时钟初始化的问题.进行一些补充:
1.例程可以正常显示时分秒 6 位数字,
但是例程不是从 00:00:00 开始,先修改为每次都是从 00:00:00 开始.
例程仅仅读取/初始化写入 时分秒 3 个数据,也修改为 读取/初始化写入 年月日星期时分秒 全部数据.
不论数码管是否可以显示这么多内容,都应该这么做.------例程也许起到一种引路的作用,上面修改都很容易.
2.深入一步增加花样:
设置好一个标志.例如:F_XS5S.由它来轮流显示年月日 或 时分秒.
在读取秒信号时,做一个秒数值的实时备份.如果读取的新值与备份值相同.就说明显示数据无需更新.(不用运行 BCD 到 BIN 显示数据的查表).-------没有不要反反复复对同样的数据做显示准备.可以节省大量运行时间.
如果读取的新值与备份值不同,就运行一次 年月日时分秒 数据到显示的处理,刷新一次显示数据.
同时,对这个每秒信号进行计数,当计数值≥5(也可以其它数值)时,清零这个计数器,同时反转一次标志 F_XS5S .
当 F_XS5S =0 就显示年月日.当 F_XS55=1 就显示时分秒.
3.每次上电,程序会进行一次对 1302 初始化,就必然都会从初始化数据可以运行实时时钟.-----在没有电池保护时,实际上当 1302 完全失电后,原来的运行数据会全部丢失.必须重新初始化!
但是,如果在调试时,板子没有失电,1302 也没有失电,就不应该进行实时时钟的初始化.
如何自动决定 DS1302 是否需要初始化?
方法很简单:程序重新运行时,在 1302 初始化子程序之前,首先读取一次 1302 的信息,然后,对其信息进行分析或比较,以此来决定是否需要初始化!
我们利用 1302 自带的 31 个RAM ,仅仅使用一个 RAM 就可以了.在第一次上电 1302 读取数据后,同时也读取一个 RAM 的数据,拿这个数据去比较一个特征码,相同则不用运行 1302 初始化程序,不相同则需要运行 1302 的初始化程序.
示例程序:
;------------------------------------------ ORG 0000H JMP B_REST ;================================================== ORG 050H B_REST: MOV WDTCR,#WDTOF MOV SP,#0E0H;SP[81H],范围: RAM 在 00H--0FFH. CALL Z_CRAM CALL Z_OFF8X8 ;关闭8*8点阵----仅仅51hei-5 使用 CALL GET_TIME ;读取1302 MOV A,4FH ;特征码在 4FH CJNE A,#0ABH,Z_INIT1302 ;特征码是 #0abh (也可以其它啊!) JMP Z_LOOP ;特征码相同跳转到 Z_LOOP Z_INIT1302: CALL DS1302_INIT ;特征码不同运行 1302 初始化程序
;========================================================== Z_LOOP: CALL GET_TIME ;读取1302 JNB F_1302,Z_LOOP0 ;F_1302=1刷新显示数据
CLR F_1302 CALL Z_RTCBIN Z_LOOP0: CALL B_LEDXS JMP Z_LOOP ;_________________________
DS1302_INIT: CLR RST CLR CLK NOP NOP SETB RST ;实时时钟写入 ZM0 07FH MOV R1,#80H
Z_WR1302: ;秒,分,时,天,月份,星期,年度==81H,83H,85H,97H,89H,8BH,8DH MOV R0,#00H CALL WRITE INC2 R1 COM_ R1,#86H,Z_WR1302 MOV R0,#01H ;天 CALL WRITE INC2 R1 MOV R0,#01H ;月份 CALL WRITE INC2 R1 MOV R0,#06H ;星期 CALL WRITE INC2 R1 MOV R0,#11H ;年度 CALL WRITE ZB1 F_1302 MOV R1,#0C8H MOV R0,#0ABH ;写入特征码 CALL WRITE RET
;=====================================
;读时间 数据子程序 GET_TIME: ; ;秒,分,时,天,月份,星期,年度==81H,83H,85H,97H,89H,8BH,8DH MOV R0,#40H MOV R1,#81H; 读秒 Z_GET_TIME0: CALL READ MOV @R0,A;41H, INC R1
INC R1 INC R0 COM_ R0,#047H,Z_GET_TIME0 MOV R1,#0C9H ;读出特征码;内部RAM命令与地址:C0H--FDH.奇数=读,偶数=写. CALL READ MOV 4FH,A ;读出特征码保存到4FH MOV A,40H CJNE A,7FH,Z_F1302 ;7fh 是上一次秒数值的备份 RET Z_F1302: MOV 7FH,A ;7fh 是秒数值的备份 ZB1 F_1302 ;设置刷新显示标志 INC 7EH COM_ 7EH,#5,Z_7EH ZM0 7EH CPL FRLSZ ;反转轮流显示标志 Z_7EH: RET ;============================================
经过这样补充,就可以增加显示年月日(轮流显示),以及自动判断是否需要对 DS1302 进行初始化.
仅供参考!
|