📄 12.asm
字号:
;=====液晶屏通信引脚定义=====
RS BIT P2.0
RW BIT P2.1
E BIT P2.2
DB0_DB7 EQU P0
;=====DS1302通信引脚定义=====
RST BIT P3.0
SCLK BIT P3.1
IO BIT P3.2
;=====数据设定引脚定义========
MODE BIT P3.3
JIA BIT P3.4
JIAN BIT P3.5
;=====定义数据存储地址========
DS1302_ADDR DATA 30H ;地址寄存器
DS1302_DATA DATA 31H ;数据寄存器
TIME_YEAR DATA 32H ;年寄存器
TIME_MONT DATA 33H ;月寄存器
TIME_DAY DATA 34H ;天寄存器
WEEK_DATA DATA 35H ;星期寄存器
HOUR DATA 36H ;小时寄存器
MINTUE DATA 37H ;分钟寄存器
SECOND DATA 38H ;秒钟寄存器
;=========显示数据缓冲地址============
YEAR_HBUF DATA 40H
YEAR_LBUF DATA 41H
MONT_HBUF DATA 42H
MONT_LBUF DATA 43H
DAY_HBUF DATA 44H
DAY_LBUF DATA 45H
WEEK_HBUF DATA 46H
WEEK_LBUF DATA 47H
HOUR_HBUF DATA 48H
HOUR_LBUF DATA 49H
MINTUE_HBUF DATA 4AH
MINTUE_LBUF DATA 4BH
SECOND_HBUF DATA 4CH
SECOND_LBUF DATA 4DH
;============程序开始==============
ORG 00H
AJMP START
;==================================
ORG 0050H
START:
MOV SP,#70H
LCALL INITIALZE ;调用初始化液晶屏幕
LCALL INIT_P ;调用初始画面
MOV A, #00000001B ;清液晶屏,写成空白
LCALL WRITE_COM
;============主程序================
MAIN:
LCALL RD_DS1302
LCALL DATA_BUF
LCALL DISPLAY
AJMP MAIN
;==========读1302子程序=================
RD_DS1302:
MOV DS1302_ADDR,#8DH ;读DS1302中的年
LCALL READ ;调用读DS1302子程序
MOV TIME_YEAR, DS1302_DATA ;把读出的年数据存入年寄存器中
MOV DS1302_ADDR,#8BH ;读DS1302中的星期
LCALL READ
MOV WEEK_DATA, DS1302_DATA ;把读出的星期数据存入星期寄存器中
MOV DS1302_ADDR,#89H ;读DS1302中的月
LCALL READ
MOV TIME_MONT, DS1302_DATA ;把读出的月数据存入月寄存器中
MOV DS1302_ADDR,#87H ;读DS1302中的天
LCALL READ
MOV TIME_DAY, DS1302_DATA ;把读出的天数据存入天寄存器中
MOV DS1302_ADDR,#85H ;读DS1302中的小时
LCALL READ
MOV HOUR, DS1302_DATA ;把读出的天数据存入小时寄存器中
MOV DS1302_ADDR,#83H ;读DS1302中的分钟
LCALL READ
MOV MINTUE, DS1302_DATA ;把读出的天数据存入分钟寄存器中
MOV DS1302_ADDR,#81H ;读DS1302中的秒钟
LCALL READ
MOV SECOND, DS1302_DATA ;把读出的天数据存入秒钟寄存器中
RET
;===========按键子程序=================
;=========数据分离后送显示缓存==================
DATA_BUF:
MOV R0,TIME_YEAR ;年数据分离,送显示缓存
LCALL DIVIDE
MOV YEAR_HBUF,R1
MOV YEAR_LBUF,R2
MOV R0,TIME_MONT ;月数据分离,送显示缓存
LCALL DIVIDE
MOV MONT_HBUF,R1
MOV MONT_LBUF,R2
MOV R0,TIME_DAY ;日数据分离,送显示缓存
LCALL DIVIDE
MOV DAY_HBUF,R1
MOV DAY_LBUF,R2
MOV R0,WEEK_DATA ;星期数据分离,送显示缓存
LCALL DIVIDE
MOV WEEK_HBUF,R1
MOV WEEK_LBUF,R2
MOV R0,HOUR ;小时数据分离,送显示缓存
LCALL DIVIDE
MOV HOUR_HBUF,R1
MOV HOUR_LBUF,R2
MOV R0,MINTUE ;分钟数据分离,送显示缓存
LCALL DIVIDE
MOV MINTUE_HBUF,R1
MOV MINTUE_LBUF,R2
MOV R0,SECOND ;秒钟数据分离,送显示缓存
LCALL DIVIDE
MOV SECOND_HBUF,R1
MOV SECOND_LBUF,R2
RET
;=========日历显示子程序==========
DISPLAY:
MOV A,#10000001B ;设定年第1位的显示地址为第1行,第1列
LCALL WRITE_COM
MOV A, #32H ;数字2的ASCII码
LCALL WRITE_DATA
MOV A,#10000010B ;设定年第2位的显示地址为第1行,第2列
LCALL WRITE_COM
MOV A, #30H ;数字0的ASCII码
LCALL WRITE_DATA
MOV A,#10000011B ;设定年第3位的显示地址为第1行,第3列
LCALL WRITE_COM
MOV A, YEAR_LBUF ;年的底位缓存数据
ADD A,#30H ;加30H修正取ASCII码
LCALL WRITE_DATA
MOV A,#10000100B ;设定年第4位的显示地址为第1行,第4列
LCALL WRITE_COM
MOV A, YEAR_HBUF ;年的高位缓存数据
ADD A,#30H ;加30H修正取ASCII码
LCALL WRITE_DATA
MOV A,#10000101B ;设定斜线的显示地址为第1行,第5列
LCALL WRITE_COM
MOV A,#2FH ;斜线的ASCII码
LCALL WRITE_DATA
MOV A,#10000110B ;设定月第1位的显示地址为第1行,第6列
LCALL WRITE_COM
MOV A, MONT_LBUF ;月的低位缓存数据
ADD A,#30H ;加30H修正取ASCII码
LCALL WRITE_DATA
MOV A,#10000111B ;设定月第2位的显示地址为第1行,第7列
LCALL WRITE_COM
MOV A, MONT_HBUF ;月的高位缓存数据
ADD A,#30H ;加30H修正取ASCII码
LCALL WRITE_DATA
MOV A,#10001000B ;设定斜线的显示地址为第1行,第8列
LCALL WRITE_COM
MOV A,#2FH ;斜线的ASCII码
LCALL WRITE_DATA
MOV A,#10001001B ;设定天第1位的显示地址为第1行,第9列
LCALL WRITE_COM
MOV A, DAY_LBUF ;天的低位缓存数据
ADD A,#30H ;加30H修正取ASCII码
LCALL WRITE_DATA
MOV A,#10001010B ;设定天第2位的显示地址为第1行,第10列
LCALL WRITE_COM
MOV A, DAY_HBUF ;天的高位缓存数据
ADD A,#30H ;加30H修正取ASCII码
LCALL WRITE_DATA
MOV A,#10001101B ;设定星期第2位的显示地址为第1行,第13列
LCALL WRITE_COM
MOV A, WEEK_DATA ;星期的高位缓存数据
SUBB A,#1
ADD A,#30H ;加30H修正取ASCII码
LCALL WRITE_DATA
MOV A,#11000000B ;设定小时第1位的显示地址为第2行,第0列
LCALL WRITE_COM
MOV A, HOUR_LBUF ;小时的低位缓存数据
ADD A,#30H ;加30H修正取ASCII码
LCALL WRITE_DATA
MOV A,#11000001B ;设定小时第2位的显示地址为第2行,第1列
LCALL WRITE_COM
MOV A, HOUR_HBUF ;小时的高位缓存数据
ADD A,#30H ;加30H修正取ASCII码
LCALL WRITE_DATA
MOV A,#11000010B ;设定冒号的显示地址为第2行,第2列
LCALL WRITE_COM
MOV A, #3AH ;冒号的ASCII码
LCALL WRITE_DATA
MOV A,#11000011B ;设定分钟第1位的显示地址为第2行,第3列
LCALL WRITE_COM
MOV A, MINTUE_LBUF ;分钟的低位缓存数据
ADD A,#30H ;加30H修正取ASCII码
LCALL WRITE_DATA
MOV A,#11000100B ;设定分钟第2位的显示地址为第2行,第4列
LCALL WRITE_COM
MOV A, MINTUE_HBUF ;分钟的高位缓存数据
ADD A,#30H ;加30H修正取ASCII码
LCALL WRITE_DATA
MOV A,#11000101B ;设定冒号的显示地址为第2行,第5列
LCALL WRITE_COM
MOV A, #3AH ;冒号的ASCII码
LCALL WRITE_DATA
MOV A,#11000110B ;设定秒钟第1位的显示地址为第2行,第6列
LCALL WRITE_COM
MOV A, SECOND_LBUF ;秒钟的低位缓存数据
ADD A,#30H ;加30H修正取ASCII码
LCALL WRITE_DATA
MOV A,#11000111B ;设定秒钟第2位的显示地址为第2行,第7列
LCALL WRITE_COM
MOV A, SECOND_HBUF ;秒钟的高位缓存数据
ADD A,#30H ;加30H修正取ASCII码
LCALL WRITE_DATA
RET
;=========初始画面==============
INIT_P:
MOV A,#10000000B ;设定显示地址1000为第1行,1010为第0列
LCALL WRITE_COM ;调用写液晶指令子程序
MOV DPTR,#LINE1
LCALL DISP
MOV A,#11000000B ;设定显示地址1100为第2行,1010为第0列
LCALL WRITE_COM ;调用写液晶指令子程序
MOV DPTR,#LINE2
LCALL DISP
LCALL DELAY2 ;调用延时2秒程序
RET
;=========显示的字符串============
LINE1: DB ' Welcome To '
LINE2: DB ' WWW.5d6d.com '
;========液晶初始化===============
INITIALZE:
MOV A, #00111000B ;8位数据,双行显示,5-7字型
LCALL WRITE_COM ;调用写液晶指令
MOV A, #00001100B ;显示屏开启,光标出现在地址计数器位置,光标不闪烁
LCALL WRITE_COM ;调用写液晶指令
MOV A, #00000110B ;光标右移一格,AC值加一,字符全部不动
LCALL WRITE_COM ;调用写液晶指令
CLR A
;========DS1302初始化===========
MOV DS1302_ADDR, #8EH ;写DS1302控制指令
MOV DS1302_DATA, #00H ;写数据到DS1302的8E控制寄存器中,允许对其进行写操作
LCALL WRITE ;调用写DS1302子程序
MOV DS1302_ADDR, #90H ;写DS1302控制指令
MOV DS1302_DATA,#0A6H ;写数据到DS1302的90控制寄存器中,对电池涓流充电,充电电流为1.1mA
LCALL WRITE ;调用写DS1302子程序
RET
;=========查询忙碌标志============
CHECK_BUSY:
PUSH ACC
BUSY_LOOP:
CLR E
SETB RW
CLR RS
SETB E
MOV A, DB0_DB7
JB p0.7,BUSY_LOOP
POP ACC
LCALL DEL
RET
;=========写指令到液晶=============
WRITE_COM:
LCALL CHECK_BUSY
CLR E
CLR RS
CLR RW
SETB E
MOV DB0_DB7,A
CLR E
RET
;==========写数据到液晶==============
WRITE_DATA:
LCALL CHECK_BUSY
CLR E
SETB RS
CLR RW
SETB E
MOV DB0_DB7,A
CLR E
RET
;===========延时程序===================
DEL:
MOV R6,#5
L1:
MOV R7,#248
DJNZ R7,$
DJNZ R6,L1
RET
;===========显示字符串到LCM==============
DISP:
PUSH ACC
DISP_LOOP:
CLR A
MOVC A,@A+DPTR
JZ END_DISP ;若A的内容为0.则终止查表
LCALL WRITE_DATA
INC DPTR
SJMP DISP_LOOP
END_DISP:
POP ACC
RET
;***********写1302程序*************
WRITE:
CLR SCLK
NOP
SETB RST
NOP
MOV A,DS1302_ADDR
MOV R4,#8
WRITE1:
RRC A ;送地址给1302
NOP
NOP
CLR SCLK
NOP
NOP
NOP
MOV IO,C
SETB SCLK ;送入地址在时钟上升沿有效
NOP
NOP
NOP
NOP
DJNZ R4,WRITE1
CLR SCLK
NOP
MOV A,DS1302_DATA
MOV R4,#8
WRITE2:
RRC A
NOP ;送数据给1302,时钟上升沿,数据输入
CLR SCLK
NOP
NOP
MOV IO,C
NOP
NOP
NOP
SETB SCLK
NOP
NOP
DJNZ R4,WRITE2
CLR RST
CLR A
RET
;**********读1302程序************
READ:
CLR SCLK
NOP
NOP
SETB RST
NOP
MOV A,DS1302_ADDR
MOV R4,#8
READ1:
RRC A
NOP
MOV IO,C
NOP
NOP
NOP
SETB SCLK ;送入地址在时钟上升沿有效
NOP
NOP
NOP
CLR SCLK
NOP
NOP
DJNZ R4,READ1 ;判断8位数据是否传送完
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -