📄 ds1302.asm
字号:
list p=16f877
include <p16f877.inc>
sec_rx equ 60h ;收到的秒,分,时,星期,日,月,年数据依次传入60H~66H
min_rx equ 61h
hou_rx equ 62h
date_rx equ 63h
mon_rx equ 64h
day_rx equ 65h
year_rx equ 66h
sec equ 70h ;发送的秒,分,时,星期,日,月,年数据依次传入70H~76H
min equ 71h
hou equ 72h
date equ 73h
mon equ 74h
day equ 75h
year equ 76h
wrenable equ 77h ;写使能寄存器
time_tx equ 78h ;DS1302当前发送寄存器
time_rx equ 79h ;DS1302当前接收寄存器
time_rx_total equ 60H ;保存接受的7个数据(一次过接受的起始地址)
time_tx_total equ 70H
count1 equ 20h
count2 equ 21h
;******************************
bank1 macro
bsf status,rp0
endm
bank0 macro
bcf status,rp0
endm
org 00h
nop
main
call use1302
call delay245ms
loop
clrf portc
movf sec_rx,w
movwf portc
call delay245ms
call delay245ms
call delay245ms
call delay245ms
call get_time
goto loop
;使用ds1302 *
;*******************
use1302
call ini_port
call ini_ds1302
call set_time
call get_time
return
;************************************初始化与1302相连的3个端口**********************************
;***********************************************************************************************
ini_port
bank1
movlw 00h ;C端口设为输出
movwf trisc
movlw 07h ;A端口与E端口-样,设为普通I/O口需要把07h赋予adcon1
movwf adcon1
movlw 00h ;A端口设为输出
movwf trisa
bank0
return
;************************************对1302进行初始化子程序*************************************
;***********************************************************************************************
ini_ds1302
bcf portc,6 ;SCLK(RC6)先置为低电平
bcf porta,0 ;RST(RA0)先禁止
movlw b'10001110' ;写使能寄存器(10001110)
movwf time_tx
bsf porta,0 ;RST(RA0)置高位,才可以对1302进行操作
call time_write
movlw 00h ;将00h送写寄存器(10001110),准确说令bit7这个wp位置置0,允许写使能
movwf time_tx
call time_write
bcf porta,0 ;RST(RA0)置0,停止对1302操作
;以下设置默认时间,默认为:04年1月1日星期一0时0分0秒
movlw b'00000110' ;其中置秒寄存器首位为0,才能让1302的晶振确保起振
movwf sec
movlw .0
movwf min
movlw .0
movwf hou
movlw .1
movwf date
movlw .1
movwf mon
movlw .1
movwf day
movlw b'00000100'
movwf year
call set_time
return
;***********************************1302一次性设定时间子程序***********************************
;**********************************************************************************************
set_time
movlw b'10111110' ;突发模式写入(10111110是突发模式写入命令)
movwf time_tx
bsf porta,0 ;RST(RA0)置高位,才可以对1302进行操作
call time_write ;以下为发送8个数据
movlw time_tx_total ;发送数据的起始地址到fsr
movwf fsr
movlw .8
movwf count2
setlp
movf indf,w ;将fsr指示的地址的内容进行发送
movwf time_tx
call time_write
incf fsr,f ;fsr递增
decfsz count2,1 ;循环八次发送8个字节数据
goto setlp
bcf porta,0 ;RST(RA0)置0,停止对1302操作
return
;***********************************1302一次性读取时间子程序***********************************
;**********************************************************************************************
get_time
movlw b'10111111' ;突发模式读取(10111111是突发模式读取命令)
movwf time_tx
bsf porta,0 ;RST(RA0)置高位,才可以对1302进行操作
call time_write ;以下为读取8个数据
movlw time_rx_total ;发送数据的起始地址到fsr
movwf fsr
movlw .7
movwf count2
getlp
call time_read
movf time_rx,w
movwf indf ;将收到的数据作为fsr指示的地址的内容
incf fsr,f ;fsr递增
decfsz count2,1 ;循环七次收到7个字节数据
goto getlp
bcf porta,0 ;RST(RA0)置0,停止对1302操作
return
;***************************************1302写一字节分程序*************************************
;**********************************************************************************************
time_write ;往1302写一字节原则:sclk(RC6)给予上升沿开始进行写操作,i/o(RC7)发送数据
movlw .8
movwf count1
wrlp
bcf portc,7 ;i/o(RC7)默认值是低电平
bcf portc,6 ;先让sclk(RC6)为低电平
btfsc time_tx,0 ;测试当前发送的那位数是1还是0
bsf portc,7 ;要发送1才置i/o(RC7)高电平,0就不用专门设置,使用默认值0即可
rrf time_tx,f ;发送的数据右移
bsf portc,6 ;让sclk(RC6)为高电平,给予上升沿发送数据
decfsz count1,f ;循环八次写一字节
goto wrlp
bcf portc,6 ;恢复sclk(RC6)为低电平
return
;*************************************1302读取一个字节分程序************************************
;***********************************************************************************************
time_read ;往1302读一字节原则:sclk(RC6)给予下降沿开始进行读操作,i/o(RC7)收取数据
bank1
bsf trisc,7 ;i/o(RC7)变为输入
bank0
movlw .8
movwf count1
relp
bcf portc,6 ;让sclk(RC6)为低电平,产生下降沿开始读取
bcf status,c ;清进位,让收到的那位数据默认为0
btfsc portc,7 ;判断收到的是否为1
bsf status,c ;是1就令进位为1,是0就用默认值0即可
rrf time_rx,f ;进位通过在time_rx右移
bsf portc,6 ;sclk(RC6)恢复高电平
decfsz count1,f ;循环八次读取一字节
goto relp
bank1
bcf trisc,7 ;i/o(RC7)重新设为输出
bank0
bcf portc,6 ;sclk(RC6)回复低电平
return
;************************************************************************************************
;*****************1302(其实其他器件的数据要显示都需要)数据显示前准备子程序*********************
;************************************************************************************************
ds1302predis ;端口io转换需要延时
bank1
movlw 00h ;令D端口为输出
movwf trisd
bank0
call delay1ms ;延时1ms
return
delay250ms
movlw .251
movwf count1
de1
movlw .250
movwf count2
de2
nop
decfsz count2,1
goto de2
decfsz count1,1
goto de1
retlw 0
;*********************************************
;*******************延时函数******************
delay
lp3 movlw 64h
movwf 20h
lp0 movlw 64h
movwf 21h
lp1 decfsz 21h,1
goto lp1
decfsz 20h,1
goto lp0
decfsz 22h,1
goto lp3
return
;******************延时245ms******************
delay245ms
movlw .246
movwf count1
de245lp1
movlw .250
movwf count2
de245lp2
nop
decfsz count2,1
goto de245lp2
decfsz count1,1
goto de245lp1
retlw 0
;********************************************
;******************延时86ms******************
delay86ms
movlw .87
movwf count1
de86mslp1
movlw .250
movwf count2
de86mslp2
nop
decfsz count2,1
goto de86mslp2
decfsz count1,1
goto de86mslp1
retlw 0
;********************************************
;******************延时20ms******************
delay20ms
movlw .21
movwf count1
de20mslp1
movlw .250
movwf count2
de20mslp2
nop
decfsz count2,1
goto de20mslp2
decfsz count1,1
goto de20mslp1
retlw 0
;*********************************************
;******************延时1ms********************
delay1ms
movlw .6
movwf count1
de1mslp1
movlw .5
movwf count2
de1mslp2
nop
decfsz count2,1
goto de1mslp2
decfsz count1,1
goto de1mslp1
retlw 0
end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -