📄 ds1302.txt
字号:
DIN BIT P1.0 ;MAX7219的接口
CLK BIT P1.1
LOAD BIT P1.2
HW BIT P1.4 ;0038红外数据口
SCL BIT P3.4 ;AT24C256接口
SDA BIT P3.5
SCLK BIT P1.7 ;DS1302时钟接口
IO BIT P1.6
RST BIT P1.5
DQ BIT P1.3 ;DS18B20数据口
TL EQU 30H
TH EQU 31H
TN EQU 32H
DISP_REG EQU 35H ;闪烁缓存器
T_REG EQU 36H ;时间修改控制寄存器
CHANGE_BUFFER EQU 3EH ;修改时间值的时候,暂存读数值
DISP EQU 3FH ;显示指针
T_BUFFER EQU 40H ;暂存8字节时钟数据
T_SHUJU EQU 58H
FLAG1 BIT 00H
SHANSHUOBIT BIT 01H ;用于存储闪烁的状态
ORG 0000H
LJMP MAIN
ORG 0003H
LJMP INT0
ORG 0013H
LJMP INT1
ORG 0100H
MAIN:
MOV T_REG,#0 ;时间修改控制寄存器
CLR SHANSHUOBIT
MOV DISP_REG,#0
MOV IE, #00000101B ;设置并开中断
MOV IP, #00000100B ;中断1的优先级高于中断0
CLR IT0
CLR IT1
SETB EA
ACALL MAX7219_CONFIG
ACALL DS1302_CONFIG
PPP:
ACALL READ_DS1302_8B
ACALL DS1302_CHULI
ACALL GET_TEMPER
ACALL TEMPER_COV
ACALL DISPLAY
SJMP PPP
SJMP $
;-------------------------以下为各部分子程序
;-------------------------显示子程序,显示8位,显示数据存储于50-57h,显示右边为50h
DISPLAY:
;由DISP决定显示什么内容
MOV R0,DISP
MOV R4,#01H
MOV R3,#08H
DISPLAY0:
MOV A,@R0
MOV B,A
MOV A,R4
LCALL W_7219
INC R0
INC R4
DJNZ R3,DISPLAY0
RET
;-------------------MAX7219的初始设置,a为命令地址,b为发送的设置数据
MAX7219_CONFIG:
MOV A,#0BH ;扫描几位数码管,扫描8个
MOV B,#7
LCALL W_7219
MOV A,#09H ;译码模式
MOV B,#00H
LCALL W_7219
MOV A,#0AH ;亮度设置
MOV B,#0BH
LCALL W_7219
MOV A,#0CH ;关断模式,为1正常
MOV B,#01H
LCALL W_7219
MOV DISP,#58H ;初始显示时间
RET
;--------------写MAX7219,写的地址存于A,数据存于B
W_7219:
CLR LOAD
LCALL SD_7219
MOV A,B
LCALL SD_7219
SETB LOAD
RET
;--------------发送数据到MAX7219,数据存于A
SD_7219:
MOV R6,#08H
SD_72191:NOP
CLR CLK
RLC A
MOV DIN,C
NOP
SETB CLK
DJNZ R6,SD_72191
RET
;------------------读出转换后的温度值
GET_TEMPER:
SETB DQ ; 定时入口
BCD:
LCALL INIT_1820
JB FLAG1,S22
LJMP BCD ; 若DS18B20不存在则返回
S22:
LCALL DELAY64US
MOV A,#0CCH ; 跳过ROM匹配------0CC
LCALL WRITE_1820
MOV A,#44H ; 发出温度转换命令
LCALL WRITE_1820
NOP
LCALL DELAY
LCALL DELAY
CBA:
LCALL INIT_1820
JB FLAG1,ABC
LJMP CBA
ABC:
LCALL DELAY64US
MOV A,#0CCH ; 跳过ROM匹配
LCALL WRITE_1820
MOV A,#0BEH ; 发出读温度命令
LCALL WRITE_1820
LCALL READ_18200 ;READ_1820
RET
;------------------读DS18B20的程序,从DS18B20中读出一个字节的数据
READ_1820:
MOV R2,#8
RE1:
CLR C
SETB DQ
NOP
NOP
CLR DQ
NOP
NOP
NOP
SETB DQ
MOV R3,#7
DJNZ R3,$
MOV C,DQ
MOV R3,#23
DJNZ R3,$
RRC A
DJNZ R2,RE1
RET
;-------------------写DS18B20的程序
WRITE_1820:
MOV R2,#8
CLR C
WR1:
CLR DQ
MOV R3,#6
DJNZ R3,$
RRC A
MOV DQ,C
MOV R3,#23
DJNZ R3,$
SETB DQ
NOP
DJNZ R2,WR1
SETB DQ
RET
;-------------------读DS18B20的程序,从DS18B20中读出两个字节的温度数据
READ_18200:
MOV R4,#2 ; 将温度高位和低位从DS18B20中读出
MOV R1,#TL ; 低位存入TL,高位存入TH)
RE00:
MOV R2,#8
RE01:
CLR C
SETB DQ
NOP
NOP
CLR DQ
NOP
NOP
NOP
SETB DQ
MOV R3,#7
DJNZ R3,$
MOV C,DQ
MOV R3,#23
DJNZ R3,$
RRC A
DJNZ R2,RE01
MOV @R1,A
INC R1
DJNZ R4,RE00
RET
;-------------------将从DS18B20中读出的温度数据进行转换
TEMPER_COV:
MOV DPTR,#WENDUBCD
MOV A,TH
ANL A,#00000111B
SWAP A
MOV TN,A
MOV A,TL
ANL A,#11110000B
SWAP A
ADD A,TN
MOV B,#100
DIV AB
MOVC A,@A+DPTR
MOV 54H,A
MOV A,B
MOV B,#10
DIV AB
MOVC A,@A+DPTR
MOV 53H,A
MOV A,B
MOVC A,@A+DPTR
ORL A,#10000000B ;加小数点
MOV 52H,A ;处理完整数部分
MOV A,TL
ANL A,#00001111B
MOV DPTR,#XIAOSHUDIAN
MOVC A,@A+DPTR
MOV DPTR,#WENDUBCD
MOVC A,@A+DPTR
MOV 51H,A
MOV 50H,#0DH
MOV 55H,#00000001B
MOV 56H,#01100111B
MOV 57H,#01000110B
RET
;-------------------DS18B20初始化程序
INIT_1820:
SETB DQ
NOP
CLR DQ
MOV R0,#240
TSR1:
DJNZ R0,TSR1 ; 延时
SETB DQ
MOV R0,#25 ;96US-25H
TSR2:
DJNZ R0,TSR2
JNB DQ,TSR3
LJMP TSR4 ; 延时
TSR3:
SETB FLAG1 ; 置标志位,表示DS1820存在
LJMP TSR5
TSR4:
CLR FLAG1 ; 清标志位,表示DS1820不存在
LJMP TSR7
TSR5:
MOV R0,#100 ;200US
TSR6:
DJNZ R0,TSR6 ; 延时
TSR7:
SETB DQ
RET
;------------------重新写DS18B20暂存存储器设定值
DS18B20_CONFIG:
RE_CONFIG1:
LCALL INIT_1820
JNB FLAG1,RE_CONFIG1 ; 若DS18B20不存在,转RE_CONFIG1
MOV A,#0CCH ; 发SKIP ROM命令
LCALL WRITE_1820
MOV A,#4EH ; 发写暂存存储器命令
LCALL WRITE_1820
MOV A,#00H ; TH(报警上限)中写入00H
LCALL WRITE_1820
MOV A,#00H ; TL(报警下限)中写入00H
LCALL WRITE_1820
MOV A,#7FH ; 选择12位温度分辨率
LCALL WRITE_1820
RET
;------------------延时子程序
DELAY:
MOV R7,#00H
MIN:
DJNZ R7,YS500
RET
YS500:
LCALL DELAY500US
LJMP MIN
DELAY500US:
MOV R6,#00H
DJNZ R6,$
RET
DELAY64US:
MOV R7,#20H
DJNZ R7,$
RET
WENDUBCD:
DB 7EH,30H,6DH,79H,33H,5BH,5FH,70H,7FH,7BH,77H,1FH,4EH,3DH,4FH,47H
XIAOSHUDIAN:
DB 00H,00H,01H,01H,02H,03H,03H,04H,05H,05H,06H,07H,07H,08H,08H,09H
;------------------DS1302相关子程序
;-----------------------------------------------------------
DS1302_CHULI: ;原始数据放在T_BUFFER为首址的8位字节里
MOV R1,#T_BUFFER ;处理后的bcd码放在T_SHUJU的后十六字节内,分别是[秒个位、秒十位
MOV R0,#T_SHUJU ;分个位、分十位、小时个位、小时十位 、空、星期] 第一页八字节
MOV DPTR,#WENDUBCD
;----------------------上面为设置数据指针
MOV A,@R1 ;提取秒信息
MOV B,A
ANL A,#00001111B
MOVC A,@A+DPTR
MOV @R0,A ;提取秒的个位并将二进制码放入秒个位寄存器
MOV A,B
ANL A,#01110000B
SWAP A
INC R0
MOVC A,@A+DPTR
MOV @R0,A ;提取秒的十位并将二进制码放入秒个位寄存器
;----------------------秒信息处理完
INC R1
MOV A,@R1 ;对应的分寄存器
MOV B,A
ANL A,#00001111B
INC R0
MOVC A,@A+DPTR
ORL A,#10000000B ;处理小数点
MOV @R0,A ;提取分的个位并将二进制码放入秒个位寄存器
MOV A,B
ANL A,#01110000B
SWAP A
INC R0
MOVC A,@A+DPTR
MOV @R0,A ;提取分的十位并将二进制码放入秒个位寄存器
;----------------------分信息处理完
INC R1
MOV A,@R1 ;对应的小时寄存器
MOV B,A
ANL A,#00001111B
INC R0
MOVC A,@A+DPTR
ORL A,#10000000B ;处理小数点
MOV @R0,A ;提取小时的个位并将二进制码放入秒个位寄存器
MOV A,B
ANL A,#01110000B
SWAP A
INC R0
MOVC A,@A+DPTR
MOV @R0,A ;提取小时的十位并将二进制码放入秒个位寄存器
;----------------------小时信息处理完
INC R1 ;提前处理星期信息,故指针加两次
INC R1
INC R0
MOV @R0,#0 ;空一个数据,其位0
INC R1
MOV A,@R1 ;对应的星期寄存器
ANL A,#00000111B
INC R0
MOVC A,@A+DPTR
MOV @R0,A ;提取星期并将二进制码放入秒个位寄存器
;----------------------星期信息处理完
DEC R1 ;恢复顺序处理,故指针再减两次
DEC R1
INC R1
MOV A,@R1 ;对应的日期寄存器
MOV B,A
ANL A,#00001111B
INC R0
MOVC A,@A+DPTR
MOV @R0,A ;提取日期的个位并将二进制码放入秒个位寄存器
MOV A,B
ANL A,#01110000B
SWAP A
INC R0
MOVC A,@A+DPTR
MOV @R0,A ;提取日期的十位并将二进制码放入秒个位寄存器
;----------------------日期信息处理完
INC R1
MOV A,@R1 ;对应的月期寄存器
MOV B,A
ANL A,#00001111B
INC R0
MOVC A,@A+DPTR
ORL A,#10000000B ;处理小数点
MOV @R0,A ;提取月的个位并将二进制码放入秒个位寄存器
MOV A,B
ANL A,#01110000B
SWAP A
INC R0
MOVC A,@A+DPTR
MOV @R0,A ;提取月的十位并将二进制码放入秒个位寄存器
;----------------------月信息处理完
INC R1
INC R1 ;跳过了星期的处理
MOV A,@R1 ;对应的年寄存器
MOV B,A
ANL A,#00001111B
INC R0
MOVC A,@A+DPTR
ORL A,#10000000B ;处理小数点
MOV @R0,A ;提取年的个位并将二进制码放入秒个位寄存器
MOV A,B
ANL A,#01110000B
SWAP A
INC R0
MOVC A,@A+DPTR
MOV @R0,A ;提取年的十位并将二进制码放入秒个位寄存器
;直接给年的千位百位赋值得,固定为2和0
INC R0
MOV A,#0
MOVC A,@A+DPTR
MOV @R0,A
INC R0
MOV A,#2
MOVC A,@A+DPTR
MOV @R0,A
RET
DS1302_CONFIG: ;设置DS1302
MOV A,#8EH ;打开写允许
MOV B,#00H
ACALL WRITE_DS1302
MOV A,#90H
MOV B,#10100110B ;允许充电,选择一个二极管和4k的电阻
ACALL WRITE_DS1302
MOV A,#81H ;先读出原秒时间,再和原来的秒时间一起打开计时控制位
ACALL READ_DS1302
CLR ACC.7
MOV B,A ;打开计时控制位
MOV A,#80H
ACALL WRITE_DS1302
MOV A,#8EH ;关闭写允许
MOV B,#80H
ACALL WRITE_DS1302
RET
WRITE_DS1302: ;地址以及读写命令放在A中,所写数据放在B中
MOV R2,#8 ;每次发送八位数据
CLR RST
NOP
CLR SCLK
NOP
SETB RST
WRDS13020: ;写入8为地址命令码
RRC A
NOP
MOV IO,C
NOP
SETB SCLK
NOP
CLR SCLK
DJNZ R2,WRDS13020
MOV R2,#8 ;8位数据
MOV A,B ;将数据给A
WRDS13021:
RRC A
NOP
MOV IO,C
NOP
SETB SCLK
NOP
CLR SCLK
DJNZ R2,WRDS13021
CLR RST
RET
READ_DS1302: ;地址以及读写命令放在A中,所读出数据放在A中
MOV R2,#8 ;每次发送八位数据
CLR RST
NOP
CLR SCLK
NOP
SETB RST
REDS13020: ;写入8为地址命令码
RRC A
NOP
MOV IO,C
NOP
SETB SCLK
NOP
CLR SCLK
DJNZ R2,REDS13020
MOV R2,#8 ;8位数据
CLR A
CLR C ;先清空c
REDS13021:
NOP
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -