找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開(kāi)始

帖子
查看: 3704|回復(fù): 19
打印 上一主題 下一主題
收起左側(cè)

DS1302時(shí)鐘求助

  [復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
       本人用AT89C51和DS1302 抄別人的軟件 制作了個(gè)時(shí)鐘,時(shí)鐘倒是可以正常走時(shí),只是有個(gè)問(wèn)題,斷電后重新通電,時(shí)間不能顯示當(dāng)時(shí)時(shí)間,會(huì)回到初始化時(shí)間,時(shí)間需要重新調(diào)整,感覺(jué)是程序中少了實(shí)時(shí)時(shí)間處理這個(gè)代碼,DS1302已經(jīng)安裝了電池,本人單片機(jī)不經(jīng)常使用,自學(xué)了匯編后只會(huì)匯編,C只能看個(gè)大概,哪個(gè)高手幫幫忙看看這程序需要如何改才可以時(shí)時(shí)顯示時(shí)間,只要顯示 秒分時(shí)  時(shí)間就可以了,其他功能不需要,謝謝!

T_CLK Bit P1.6                    ;實(shí)時(shí)時(shí)鐘時(shí)鐘線引腳
T_IO  Bit P1.5                         ;實(shí)時(shí)時(shí)鐘數(shù)據(jù)線引腳
T_RST Bit P1.4                         ;實(shí)時(shí)時(shí)鐘復(fù)位線引腳

D6 BIT P2.0    ;小時(shí)十位數(shù)碼管
D5 BIT P2.1    ;小時(shí)個(gè)位數(shù)碼管
D4 BIT P2.2     ;分鐘十位數(shù)碼管
D3 BIT P2.3     ;分鐘個(gè)位數(shù)碼管
D2 BIT P2.4     ;秒十位數(shù)碼管
D1 BIT P2.5     ;秒個(gè)位數(shù)碼管


D_OUT EQU P0 ;數(shù)碼管段位連接端

DOT BIT 20H.0
POT BIT 20H.1
second     EQU     60h ;秒的緩沖區(qū)
minute     EQU     61h ;分的緩沖區(qū)
hour         EQU      62h ;小時(shí)的緩沖區(qū)
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初始時(shí)間
lcall GET1302          ;DS1302讀取時(shí)間
lcall  DSP               ;顯示時(shí)間子程序
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                  ;顯示時(shí)間子程序

lp2: djnz r3,lp1                 ;未到1 S繼續(xù)循環(huán)
     mov  r3,#20
     cpl dot
     CJNE R1,#5FH,LP1
     lcall GET1302                ;每過(guò)1s從DS1302讀取一次時(shí)間

lp1:pop psw
    pop acc
    reti

;****************************************************

;顯示時(shí)間掃描子程序
DSP:   CJNE R1,#60H,SS

。。。。。。。此次有代碼省略

DSP3: RET

;---------------------------------------------------------------------------------------------------
;設(shè)置DS1302初始時(shí)間,并啟動(dòng)計(jì)時(shí)
SETDS1302:
        CLR     T_RST
        nop
        CLR     T_CLK
        nop
        SETB    T_RST
        nop
        MOV     B,#8EH          ;寫控制命令字
        LCALL   INPUTBYTE      
        MOV     B,#00H          ;寫保護(hù)關(guān)閉
        LCALL   INPUTBYTE
        SETB    T_CLK
        nop
        CLR     T_RST

        MOV     R0,#SECOND      ;內(nèi)存中的時(shí)間首地址
        MOV     R2,#80H         ;DS1302中的時(shí)間首地址
        MOV     R7,#7           ;字節(jié)數(shù)

SETLOOP:
        CLR     T_RST
        nop
        CLR     T_CLK
        nop
        SETB    T_RST
        nop
        MOV     B,R2            ;寫命令字
        LCALL   INPUTBYTE
        MOV     A,@R0           ;設(shè)置時(shí)間
        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          ;開(kāi)寫保護(hù)
        LCALL   INPUTBYTE
        SETB    T_CLK
        nop
        CLR     T_RST
        nop
        RET

;---------------------------------------------------------------------------------------------------
;從DS1302讀取時(shí)間
GET1302:
        MOV     R0,#SECOND   
        MOV     R2,#81H        ;DS1302中讀時(shí)間的首地址
        MOV     R7,#7
GETLOOP:
        CLR     T_RST
        nop
        CLR     T_CLK
        nop
        SETB    T_RST
        nop
        MOV     B,R2
        LCALL   INPUTBYTE       ;寫命令字
        LCALL   OUTPUTBYTE      ;讀時(shí)間
        MOV     @R0,A           ;將從DS1302中讀取的時(shí)間從內(nèi)存中保存
        INC     R0              ;修改地址指針
        INC     R2
        INC     R2
        SETB    T_CLK
        nop
        CLR     T_RST
        nop
        DJNZ    R7,GETLOOP
        RET

;---------------------------------------------------------------------------------------------------
;向DS1302寫一個(gè)字節(jié)
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讀一個(gè)字節(jié)
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


分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復(fù)

使用道具 舉報(bào)

沙發(fā)
ID:86421 發(fā)表于 2022-8-9 08:22 | 只看該作者
匯編看不懂。但這一現(xiàn)象按C語(yǔ)言來(lái)說(shuō),可以看一下主程序中有個(gè)初始化DS1302的程序,看里面有沒(méi)有時(shí)間初始化,如有,去掉后再看看。
回復(fù)

使用道具 舉報(bào)

板凳
ID:16255 發(fā)表于 2022-8-9 11:43 | 只看該作者
你的程序應(yīng)該了每次啟動(dòng)都把1302給初始化了(我沒(méi)有仔細(xì)閱讀每一句),把時(shí)鐘寄存器覆蓋了。
我的做法是在初始化程序中讀取下圖寄存器的狀態(tài),從而判斷要不要寫入初始化參數(shù)。



回復(fù)

使用道具 舉報(bào)

地板
ID:908826 發(fā)表于 2022-8-9 15:50 | 只看該作者
我記得我當(dāng)時(shí)用3231的時(shí)候也是這種問(wèn)題,我的解決辦法是先下載一次,然后把主程序的初始化時(shí)間注釋之后再下載一次。
回復(fù)

使用道具 舉報(bào)

5#
ID:386442 發(fā)表于 2022-8-9 17:27 | 只看該作者
lcall SETDS1302     ;DS1302初始時(shí)間
回復(fù)

使用道具 舉報(bào)

6#
ID:496636 發(fā)表于 2022-8-9 20:09 | 只看該作者
板凳說(shuō)得對(duì),RC的第0個(gè)寄存器的最高位表示是否正常計(jì)時(shí),即時(shí)鐘停止標(biāo)志,在程序的初始化步可以檢測(cè)一下這位是不是1,如果是1,就是表示掉電了,要執(zhí)行時(shí)間的初始化,把保存的默認(rèn)的時(shí)間值調(diào)出來(lái)作為現(xiàn)在的時(shí)間值 ,這樣開(kāi)機(jī)后你得重新設(shè)置一下才能把它改為當(dāng)前時(shí)間。
如果判斷它是0,就是跳過(guò)時(shí)間的初始化,就用DS1302的時(shí)間值。
回復(fù)

使用道具 舉報(bào)

7#
ID:16255 發(fā)表于 2022-8-11 10:28 | 只看該作者
13205495918 發(fā)表于 2022-8-9 15:50
我記得我當(dāng)時(shí)用3231的時(shí)候也是這種問(wèn)題,我的解決辦法是先下載一次,然后把主程序的初始化時(shí)間注釋之 ...

這種方法并不是最佳解決方案。
假如以后時(shí)鐘運(yùn)行不正常了或者更換電池了,就不能自動(dòng)初始化了。
回復(fù)

使用道具 舉報(bào)

8#
ID:72088 發(fā)表于 2022-8-11 15:49 | 只看該作者
開(kāi)機(jī)讀取1302的秒,判斷最高位狀態(tài),是1就初始化,是0就正常讀取1302,顯示時(shí)間。這樣就能正常工作了,
回復(fù)

使用道具 舉報(bào)

9#
ID:76044 發(fā)表于 2022-8-11 17:17 | 只看該作者
新鄉(xiāng)家電維修 發(fā)表于 2022-8-11 15:49
開(kāi)機(jī)讀取1302的秒,判斷最高位狀態(tài),是1就初始化,是0就正常讀取1302,顯示時(shí)間。這樣就能正常工作了,

能給例程嗎?DS1302我不熟,非常感謝
回復(fù)

使用道具 舉報(bào)

10#
ID:725922 發(fā)表于 2022-8-11 18:19 | 只看該作者
我現(xiàn)在也是這個(gè)問(wèn)題,沒(méi)好意思發(fā)上來(lái),拖延了很久,打開(kāi)keil,然后玩手機(jī),然后關(guān)電腦。。
回復(fù)

使用道具 舉報(bào)

11#
ID:603753 發(fā)表于 2022-8-12 15:47 | 只看該作者
主程序的初始化時(shí)間注釋之后再下載一次。
回復(fù)

使用道具 舉報(bào)

12#
ID:624769 發(fā)表于 2022-8-12 23:04 | 只看該作者
lxm41577 發(fā)表于 2022-8-11 17:17
能給例程嗎?DS1302我不熟,非常感謝

要抄也抄好點(diǎn)的呀,這還不如C寫的呢……

把你這段程序:
START: MOV SP,#70H
        MOV SECOND,#36H
MOV MINUTE,#49H
MOV HOUR,#08H
        MOV P2,#0FFH
        MOV DPTR,#TAB
lcall SETDS1302     ;DS1302初始時(shí)間
lcall GET1302          ;DS1302讀取時(shí)間
修改成下面的:

START: MOV SP,#70H
MOV P2,#0FFH
MOV DPTR,#TAB

lcall GET1302          ;DS1302讀取時(shí)間


MOV A,SECOND
JNB ACC.7,NOT_SET_Time
MOV SECOND,#36H
MOV MINUTE,#49H
MOV HOUR,#08H
lcall SETDS1302     ;DS1302初始時(shí)間
NOT_SET_Time:
lcall GET1302          ;DS1302讀取時(shí)間



回復(fù)

使用道具 舉報(bào)

13#
ID:76044 發(fā)表于 2022-8-14 08:17 | 只看該作者
188610329 發(fā)表于 2022-8-12 23:04
要抄也抄好點(diǎn)的呀,這還不如C寫的呢……

把你這段程序:

非常感謝您的幫忙,程序運(yùn)行成功,不怕你笑話,我開(kāi)始學(xué)的是匯編,C沒(méi)怎么學(xué),所以C非常不熟悉,只能看個(gè)大概,匯編都是湊合用編程只是愛(ài)好,再次感謝
回復(fù)

使用道具 舉報(bào)

14#
ID:229502 發(fā)表于 2022-8-19 22:31 | 只看該作者
我也是網(wǎng)上抄別人的方法,斷電后時(shí)間仍在繼續(xù)走時(shí)。方法是單片機(jī)燒寫兩次,第一次把初始化時(shí)間設(shè)置好編譯后寫進(jìn)單片機(jī),二次把初始化時(shí)間注釋掉再次編譯燒寫進(jìn)單片機(jī)。樓主可以試一下。方法在stc89c52上試過(guò)多遍時(shí)間主電源斷電后走時(shí)正常
回復(fù)

使用道具 舉報(bào)

15#
ID:76044 發(fā)表于 2022-8-20 14:12 | 只看該作者
huangjingjie 發(fā)表于 2022-8-19 22:31
我也是網(wǎng)上抄別人的方法,斷電后時(shí)間仍在繼續(xù)走時(shí)。方法是單片機(jī)燒寫兩次,第一次把初始化時(shí)間設(shè)置好編譯后 ...

這個(gè)方法我先前就試過(guò),沒(méi)有成功,不過(guò)謝謝你
回復(fù)

使用道具 舉報(bào)

16#
ID:584814 發(fā)表于 2022-8-24 15:35 | 只看該作者
總結(jié)一下上面的回答,供參考:
1、問(wèn)題出在每次啟動(dòng)都先  lcall SETDS1302     ;DS1302初始時(shí)間
   解決方法:一是如14樓說(shuō)的寫二次;二是如一眾所說(shuō)直接刪除這句(可取下電池看好不好用);
                  三是給他句加個(gè)觸發(fā)條件,在需要調(diào)整時(shí)間時(shí)可以調(diào)整時(shí)間才有時(shí)鐘的樣子
2、感覺(jué)在壇子里�;斓亩嗍菬嵝牡耐婕遥捕嗖皇强瓢喑錾�,至少俺是所以僅供參考
3、匯編和C各有千秋,只是C代碼如白話文但執(zhí)行效率那個(gè)了點(diǎn)但有更多例程可以找更多樂(lè)子
回復(fù)

使用道具 舉報(bào)

17#
ID:683123 發(fā)表于 2023-3-16 14:20 | 只看該作者
DS1372供電端加一個(gè)47uf以上的電解電容,這樣通電的時(shí)候就時(shí)間就不會(huì)重置了。原來(lái)我也遇到這樣的問(wèn)題,就是這樣解決的。
回復(fù)

使用道具 舉報(bào)

18#
ID:468209 發(fā)表于 2023-3-17 12:27 來(lái)自觸屏版 | 只看該作者
滿足條件實(shí)行初始化 不滿足則跳過(guò)

Screenshot_20230317_122449_edit_1177395346551561.jpg (191.67 KB, 下載次數(shù): 107)

Screenshot_20230317_122449_edit_1177395346551561.jpg
回復(fù)

使用道具 舉報(bào)

19#
ID:72088 發(fā)表于 2023-3-18 09:21 | 只看該作者
我給你個(gè)完美的解決方法吧,這是我的程序給你截取一段:

        LCALL GET1302      ;開(kāi)機(jī)讀出DS1302的時(shí)間
        MOV A,SECOND     ;讀出的秒寄存器放入A
        ANL A,#80H               ;只保留秒寄存器最高位,判斷最高位狀態(tài)
        JZ MAIN                      ;A為0就轉(zhuǎn)移到主程序,否則就執(zhí)行初始化DS1302程序
        LCALL CSHDS1302        ;執(zhí)行初始化DS1302程序
;-----------------主程序-------------------------
MIAN:
.......



簡(jiǎn)單高效,

回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表