📄 ds1302.asm
字号:
;此程序用于ds1302驱动,但不包括da1302的RAM存储的驱动,程序中用到ch451用于时间的显示
;ch451的驱动完全拷贝ch451的驱动程序
;在程序编写的时候子程序调用了另一个子程序的时候,注意变量的传递。
;作者:王均彬,2008年10月23日
;******************************端口设定************************************
CH451_DCLK BIT P1.5 ;串行数据时钟,上升沿激活
CH451_DIN BIT P1.6 ;串行数据输出,接CH451的数据输入
CH451_LOAD BIT P1.7 ;串行命令加载,上升沿激活
CH451_DOUT BIT P3.3 ;INT1,键盘中断和键值数据输入,接CH451的数据输出
CH451_KEY DATA 30H ;存放键盘中断中读取的键值
CH451_SI EQU 00H ;有健标志位
T_CLK Bit P1.2 ;实时时钟时钟线引脚
T_IO Bit P1.1 ;实时时钟数据线引脚
T_RST Bit P1.3 ;实时时钟复位线引脚
SECOND EQU 50H ;秒寄存器
MINUTE EQU 51H ;分寄存器
HOUR EQU 52H ;时寄存器
DAY EQU 53H ;号寄存器
MONTH EQU 54H ;月寄存器
WEEK EQU 55H ;星期寄存器
YEAR EQU 56H ;年寄存器
;*******************************主程序*************************************
ORG 00H
AJMP MAIN
ORG 13H ;键盘中断向量(外部中断1)
AJMP CH451_INTER
ORG 30H
MAIN:SETB IT1 ;置外部信号为下降沿触发
CLR IE1 ;清中断标志
SETB EX1 ;允许键盘中断
CLR EA ;关总中断 (此程序不使用键盘,但使用ch451的数码管显示时间)
;$$$$$$$$$$$$$$$CH451的初始化$$$$$$$$$$
CLR CH451_SI
MOV CH451_KEY,#00H
SETB CH451_LOAD
SETB CH451_DCLK ;置为默认的高电平
SETB CH451_DIN
SETB CH451_DOUT
MOV B,#02H ;CH451内部复位
MOV A,#01H
CALL CH451_WRITE
MOV B,#05H ;CH451显示设置
MOV A,#00H ;不译码方式,8位数据,最亮
CALL CH451_WRITE ;发出命令
MOV B,#04H ;设置系统参数命令
MOV A,#03H ;低频时钟,禁止看门狗,使能键盘功能,使能显示驱动
CALL CH451_WRITE
;$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
MOV SECOND,#00H ;时间初始值的设定(注意此程序只为验证ds1302的驱动程序)
MOV MINUTE,#25H
MOV HOUR,#11H
MOV DAY,#23H
MOV MONTH,#10H
MOV WEEK,#03H
MOV YEAR,#08H
LCALL SET1302 ;调用ds1302的设置程序
CLOCK: LCALL Get1302 ;读取ds1302的时间(可用定时器定时显示)
MOV P2,SECOND ;把秒数送p2口,用于显示
MOV A,52H
ANL A,#0FH
MOV R7,#09H
ACALL CH451_WRITE_COUNT
MOV A,52H
ANL A,#10H
RR A
RR A
RR A
RR A
MOV R7,#08H ;取小时的十位并送去显示
ACALL CH451_WRITE_COUNT
MOV A,51H
SWAP A ;取分钟十位
ANL A,#0FH
MOV R7,#0BH
ACALL CH451_WRITE_COUNT
MOV A,51H
ANL A,#0FH ;取分钟个位
MOV R7,#0CH
ACALL CH451_WRITE_COUNT
MOV A,50H
SWAP A
ANL A,#0FH ;取秒个位
MOV R7,#0EH
ACALL CH451_WRITE_COUNT
MOV A,50H
ANL A,#0FH ;取秒钟个位
MOV R7,#0FH
ACALL CH451_WRITE_COUNT
AJMP CLOCK
;********************************向数码管写数据******************************************
;IN: R7,A
;OUT 无
;USE:A,B R7,DPTR,
;调用函数CH451_WRITE
CH451_WRITE_COUNT: MOV B,R7 ;加载字数据到DIG1对应的数据寄存器
MOV DPTR,#TAB1
MOVC A,@A+DPTR
ACALL CH451_WRITE
RET
;******************************CH451写入数据************************************************
;IN:A,B 待写的12位数据, 低8位在A中, 高4位在B中
;OUT:无
; USE: A, B, R7
CH451_WRITE: CLR EX1 ;禁止键盘中断
CLR CH451_LOAD ;串行数据加载线清零
MOV R7,#08H ;r7为计数器,表示8个bit
CH451_WRITE_8: RRC A ;低位在前,高位在后
CLR CH451_DCLK ;清时钟线
MOV CH451_DIN,C ;送出一位数据
SETB CH451_DCLK ;产生时钟上升沿通知CH451输入位数据
DJNZ R7,CH451_WRITE_8 ;位数据未完继续
MOV A,B ;把高4为送入a
MOV R7,#04H ;4位数据
CH451_WRITE_4: RRC A ;低位在前,高位在后
CLR CH451_DCLK ;清时钟
MOV CH451_DIN,C ;送出一位数据
SETB CH451_DCLK ;产生时钟上升沿通知CH451输入位数据
DJNZ R7,CH451_WRITE_4 ;位数据未完继续
SETB CH451_LOAD ;产生加载上升沿通知CH451处理命令数据
SETB EX1 ;允许键盘中断
RET
;******************************CH451键值读出**************************************
; IN:无
; OUT:CH451_KEY,CH451_SIN
; USE: A, R7
CH451_READ: CLR EX1 ;禁止键盘中断
CLR CH451_LOAD ;串行数据加载线清
MOV A,#07H ;读取键值命令的高4位0111B 低8为任意值
MOV R7,#04H ;忽略12位命令的低8位
CH451_READ_4: RRC A ;低位在前,高位在后
CLR CH451_DCLK ;清时钟线
MOV CH451_DIN,C ;送出一位数据
SETB CH451_DCLK ;产生时钟上升沿锁通知CH451输入位数据
DJNZ R7,CH451_READ_4 ;位数据未完继续
SETB CH451_LOAD ;产生加载上升沿通知CH451处理命令数据
CLR A ;先清除键值单元以便移位
MOV R7,#07H ;读入7位键值
CH451_READ_7: MOV C,CH451_DOUT ;读入一位数据
CLR CH451_DCLK ;产生时钟下升沿通知CH451输出下一位
RLC A ;数据移入ACC,高位在前,低位在后
SETB CH451_DCLK
DJNZ R7,CH451_READ_7 ;位数据未完继续
MOV CH451_KEY,A
SETB CH451_SI
CLR IE1 ;清中断标志,读操作过程中有低电平脉冲
SETB EX1 ;允许键盘中断
RET
;***************************** 键盘中断子程序**********************************
; IN:无
; OUT:CH451_KEY,CH451_SIN
;调用函数:CH451_READ
CH451_INTER: PUSH PSW ;现场保护
PUSH ACC
ACALL CH451_READ ;调用读键值程序
POP ACC ;恢复现场
POP PSW
RETI ;中断返回
;**************************************设置1302*******************************************
;IN:无
;功 能:设置DS1302 初始时间,并启动计时。
;调 用:RTInputByte
;OUT:无
;USE:b,a,r0,r7,r1
SET1302:CLR T_RST
CLR T_CLK
SETB T_RST
MOV B, #8EH ;控制寄存器地址
ACALL DS1302_InputByte ;调用写入程序
MOV B, #00H ;写操作前WP=0,允许写入寄存器
ACALL DS1302_InputByte ;向DS1302写命令
SETB T_CLK
CLR T_RST
MOV R0, #Second
MOV R7, #7H ;秒 分 时 日 月 星期 年
MOV R1, #80H ;秒写地址
S13021: CLR T_CLK
SETB T_RST
MOV B, R1 ;写秒 分 时 日 月 星期 年 地址
ACALL DS1302_InputByte
MOV A, @R0 ;写秒数据
MOV B, A
ACALL DS1302_InputByte
INC R0
INC R1 ;地址调整
INC R1
SETB T_CLK
CLR T_RST
DJNZ R7, S13021
CLR T_RST
CLR T_CLK
SETB T_RST
MOV B, #91H ;充电控制寄存器
ACALL DS1302_InputByte
MOV B, #0A4H ;没有电阻,一个二极管充电
ACALL DS1302_InputByte
CLR T_RST
CLR T_CLK
SETB T_RST
MOV B, #8EH ;控制寄存器
ACALL DS1302_InputByte
MOV B, #80H ;控制寄存器,WP=1,写保护
ACALL DS1302_InputByte
SETB T_CLK
CLR T_RST
RET
;***********************写1302一字节***********************************
;IN:B
;OUT:无
;USE:r6,a,b
DS1302_InputByte: MOV R6, #8H
MOV A, B
Inbit1: RRC A ;低位在前
MOV T_IO, C ;把数据加到数据线上
SETB T_CLK ;上升沿输入数据
CLR T_CLK
DJNZ R6, Inbit1
RET
;**********************读1302一字节************************************
;IN:无
;OUT:A
;USE A R5
DS1302_OutputByte: MOV R5, #8H ;数据位数
Outbit1: MOV C, T_IO
RRC A ;低位在前
SETB T_CLK
CLR T_CLK
DJNZ R5, Outbit1
RET
;********************读取DS1302**************************************
;功 能:从DS1302 读时间
;调 用:RTInputByte,RTOutputByte
;入口参数:无
;出口参数:时间保存在:Second,Minute,Hour,Day,Month,Week.YearL
;USE:A B R0 R1 R7
GET1302: MOV R0, #Second
MOV R7, #7H
MOV R1, #81H ;秒地址
G13021: CLR T_RST
CLR T_CLK
SETB T_RST
MOV B, R1 ;秒 分 时 日 月 星期 年 地址
LCALL DS1302_InputByte
LCALL DS1302_OutputByte
MOV @R0, A ;把数据送入相应的存储器
INC R0
INC R1 ;地址调整
INC R1
SETB T_CLK
CLR T_RST
DJNZ R7, G13021
RET
;*************************************************************************************************
TAB1:DB 00111111B,00000110B,01011011B,01001111B,01100110B,01101101B,01111101B,00000111B,01111111B,01101111B
TAB2:DB 01110111B,01111100B,01011000B,01011110B,01111001B,01110001B,01101111B,01110110B,00111000B,01110011B
;上为8段数码管显示的编码0-F以及部分字符
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -