📄 ds1302_lcd1602.asm
字号:
NAME DS1302_LCD
;输入后,LCD显示18:00:00
;K1,时间\日期间切换
;K4,进入修改模式
;按K4后,K1修改移动方向,K2修改数字,K3确认并退出修改模式
SCLK BIT P1.0 ;DS1302引腿定义
IO_DATA BIT P1.1
RST BIT P1.2
RS BIT P2.0 ;TS1602引腿定义
RW BIT P2.1
E BIT P2.2
BELL BIT P3.7
SHOW BIT 7FH
CHANGE BIT 7EH
CODE_SEG SEGMENT CODE
DATA_SEG SEGMENT DATA
STACK_SEG SEGMENT IDATA
RSEG DATA_SEG
DAT: DS 1
ADDR: DS 1
DIS_BUF2: DS 16
BUTTON_V: DS 1
BUTTON_S: DS 1
POINT: DS 1
YEAR1: DS 1
YEAR2: DS 1
RSEG STACK_SEG
STACK: DS 20
;--------------------------
CSEG AT 0000H
AJMP MAIN
;---------------------------
RSEG CODE_SEG
MAIN:
USING 0
MOV SP,#(STACK-1)
LCALL INI_DS1302
LCALL INI_LCD
SETB SHOW ;SHOW为1显示时间,为0显示日期
MOV YEAR1,#31h
MOV YEAR2,#39h
MOV BUTTON_V,#0F0H
MOV P1,BUTTON_V
SCAN_LP:
LCALL DIS_DS1302
MOV A,P1
ANL A,#0F0H
XRL A,BUTTON_V
JZ SCAN_LP
MOV R4,#10
LCALL DELAYMS
MOV A,P1
ANL A,#0F0H
MOV BUTTON_S,A
XRL A,BUTTON_V
JZ SCAN_LP
MOV BUTTON_V,BUTTON_S
LCALL BUTTON_PRO
AJMP SCAN_LP
;END OF MAIN
;--------------------------------------
BUTTON_PRO:
MOV A,BUTTON_V
JNB ACC.4,K1
JNB ACC.5,K2
JNB ACC.6,K3
JNB ACC.7,K4
RET
;-------------------------------------
K1:
CPL SHOW
RET
;-------------------------------------
K2:
RET
;--------------------------------------
K3:
RET
;--------------------------------------
K4:
;当CHANGE为0时,显示闪烁置CHANGE为1,进入修改程序,修改后再按一下闪烁消失
;将屏上的数据全部写入DS1302,并置CHANGE为0,并返回
SETB CHANGE ;CHANG为1时表示正在修改当中
LCALL BEEP
MOV DAT,#0DH
LCALL WR_OP
;SHOW为1显示时间,为0显示日期
JB SHOW,K4_SHOW_TIME
MOV POINT,#0C1H ;将光标定位在年的位置上
MOV DAT,POINT
LCALL WR_OP
AJMP K4_SHOW_NT
K4_SHOW_TIME:
MOV POINT,#0C4H ;将光标定位在小时的位置上
MOV DAT,POINT
LCALL WR_OP
K4_SHOW_NT:
MOV BUTTON_V,#0F0H
MOV P1,BUTTON_V
TIME_SCAN_LP:
MOV A,P1
ANL A,#0F0H
XRL A,BUTTON_V
JZ TIME_SCAN_LP
MOV R4,#10
LCALL DELAYMS
MOV A,P1
ANL A,#0F0H
MOV BUTTON_S,A
XRL A,BUTTON_V
JZ TIME_SCAN_LP
MOV BUTTON_V,BUTTON_S
LCALL TIME_BUTTON_PRO
JNB CHANGE,TIME_SCAN_END ;当CHANGE为0时表示修改已完成
AJMP TIME_SCAN_LP
;END OF MAIN
TIME_SCAN_END:
RET
;--------------------------------
TIME_BUTTON_PRO:
MOV A,BUTTON_V
JNB ACC.4,TIME_K1
JNB ACC.5,TIME_K2
JNB ACC.6,TIME_K3
JNB ACC.7,TIME_K4
RET
;----------------------------
TIME_K1:
;向右移动
;SHOW为1显示时间,为0显示日期
JB SHOW,K1_SHOW_TIME
MOV A,POINT
CJNE A,#0CAH,TK_NT
MOV POINT,#0C0H
AJMP TK1_NT1
TK_NT:
CJNE A,#0C4H,TK1_NT
INC POINT
TK1_NT:
CJNE A,#0C7H,TK1_NT1
INC POINT
TK1_NT1:
INC POINT
MOV DAT,POINT
LCALL WR_OP
RET
K1_SHOW_TIME:
MOV A,POINT
CJNE A,#0C8H,TK_NT4
MOV POINT,#0C3H
AJMP TK1_NT4
TK_NT4:
CJNE A,#0C5H,TK1_NT4
INC POINT
TK1_NT4:
INC POINT
MOV DAT,POINT
LCALL WR_OP
RET
;---------------------------
TIME_K2:
;数值改变,一是使屏幕光标闪烁处数据对应的单元增加,
LCALL RD_DAT ;读出时光标自动加1
MOV A,DAT
MOV DAT,POINT ;使光标停留在原来位置
LCALL WR_OP
CJNE A,#39H,TK2_NT
MOV A,#2FH
TK2_NT:
INC A ;使数据增加1,再写进屏幕中,光标自加1
MOV DAT,A
LCALL WR_DAT
MOV DAT,POINT ;使光标停留在原来位置
LCALL WR_OP
RET
;--------------------------
TIME_K3:
;将数屏幕里的数据都读出来合并成一个新据并进行更新,写入DS1302里面
CLR CHANGE
LCALL UPDATA_TIME
SETB SHOW
LCALL BEEP
RET
;----------------------------
TIME_K4:
RET
;----------------------------
UPDATA_TIME:
;SHOW为1显示时间,为0显示日期
MOV ADDR,#8EH
MOV DAT,#00H
LCALL WRITE_BYTE ;允许写入DS1302
JNB SHOW,K3_SHOW_TIME
CLR C
MOV DAT,#0C4H
LCALL WR_OP
LCALL RD_DAT
MOV A,DAT
SUBB A,#30H
SWAP A
ORL A,#0FH ;
MOV R5,A ;R5高四位存放时的十位,低四位全为1
LCALL RD_DAT
MOV A,DAT
SUBB A,#30H ;A高四位全为1,低四位存放时的个位
ORL A,#0F0H
ANL A,R5 ;合并
MOV ADDR,#84H
MOV DAT,A
LCALL WRITE_BYTE ;写入时钟
MOV DAT,#0C7H
LCALL WR_OP
LCALL RD_DAT
MOV A,DAT
SUBB A,#30H
SWAP A
ORL A,#0FH ;
MOV R5,A ;R5高四位存放时的十位,低四位全为1
LCALL RD_DAT
MOV A,DAT
SUBB A,#30H ;A高四位全为1,低四位存放时的个位
ORL A,#0F0H
ANL A,R5 ;合并
MOV ADDR,#82H
MOV DAT,A
LCALL WRITE_BYTE ;写入分钟
MOV ADDR,#8EH
MOV DAT,#80H
LCALL WRITE_BYTE ;禁止写入
;LCALL BEEP
RET
K3_SHOW_TIME:
CLR C
MOV DAT,#0C1H
LCALL WR_OP
LCALL RD_DAT
MOV YEAR1,DAT
MOV DAT,#0C2H
LCALL WR_OP
LCALL RD_DAT
MOV YEAR2,DAT
MOV DAT,#0C3H
LCALL WR_OP
LCALL RD_DAT
MOV A,DAT
SUBB A,#30H
SWAP A
ORL A,#0FH ;
MOV R5,A ;R5高四位存放时的十位,低四位全为1
LCALL RD_DAT
MOV A,DAT
SUBB A,#30H ;A高四位全为1,低四位存放时的个位
ORL A,#0F0H
ANL A,R5 ;合并
MOV ADDR,#8cH
MOV DAT,A
LCALL WRITE_BYTE ;写入年份
MOV DAT,#0C6H
LCALL WR_OP
LCALL RD_DAT
MOV A,DAT
SUBB A,#30H
SWAP A
ORL A,#0FH ;
MOV R5,A ;R5高四位存放时的十位,低四位全为1
LCALL RD_DAT
MOV A,DAT
SUBB A,#30H ;A高四位全为1,低四位存放时的个位
ORL A,#0F0H
ANL A,R5 ;合并
MOV ADDR,#88H
MOV DAT,A
LCALL WRITE_BYTE ;写入月份
MOV DAT,#0C9H
LCALL WR_OP
LCALL RD_DAT
MOV A,DAT
SUBB A,#30H
SWAP A
ORL A,#0FH ;
MOV R5,A ;R5高四位存放时的十位,低四位全为1
LCALL RD_DAT
MOV A,DAT
SUBB A,#30H ;A高四位全为1,低四位存放时的个位
ORL A,#0F0H
ANL A,R5 ;合并
MOV ADDR,#86H
MOV DAT,A
LCALL WRITE_BYTE ;写入日期
MOV ADDR,#8EH
MOV DAT,#80H
LCALL WRITE_BYTE ;禁止写入
;LCALL BEEP
RET
;*********************************峰鸣程序***************************************************
BEEP:
MOV R6,#100
BP_LP:
CPL BELL
MOV R7,#180
BP_LP1:
NOP
DJNZ R7,BP_LP1
DJNZ R6,BP_LP
MOV R4,#10
LCALL DELAYMS
RET
;*************************************DS1302与LCD1602交互程序*********************************
DIS_DS1302:
;将时钟读出来,并写入缓冲显示区,再显示出来
LCALL SET_BUF2 ;清空显示缓冲区
JNB SHOW,DISDATE
LCALL DIS_DS1302_TIME ;SHOW为1时,将时分秒装载入缓冲区
LCALL DIS_LINE2
RET
DISDATE:
LCALL DIS_DS1302_DATE ;SHOW为0时,将日期装入缓冲区
LCALL DIS_LINE2
RET
;----------------------------------------
DIS_DS1302_TIME:
MOV DPTR,#TIME_CHAR ;第一行显示时间相关的
LCALL DIS_LINE1
MOV ADDR,#81H ;读秒
LCALL READ_BYTE
MOV A,DAT
ANL A,#0FH
ADD A,#30H
MOV DIS_BUF2+11,A
MOV A,DAT
SWAP A
ANL A,#07H
ADD A,#30H
MOV DIS_BUF2+10,A
MOV DIS_BUF2+9,#':'
MOV ADDR,#83H
LCALL READ_BYTE
MOV A,DAT
ANL A,#0FH
ADD A,#30H
MOV DIS_BUF2+8,A
MOV A,DAT
SWAP A
ANL A,#0FH
ADD A,#30H
MOV DIS_BUF2+7,A
MOV DIS_BUF2+6,#':'
MOV ADDR,#85H
LCALL READ_BYTE
MOV A,DAT
ANL A,#0FH
ADD A,#30H
MOV DIS_BUF2+5,A
MOV A,DAT
SWAP A
ANL A,#03H
ADD A,#30H
MOV DIS_BUF2+4,A
RET
;----------------------------------------
DIS_DS1302_DATE:
MOV DPTR,#DATE_CHAR ;第一行显示日期相关
LCALL DIS_LINE1
MOV ADDR,#8BH
LCALL READ_BYTE
LCALL SHOW_DAY
MOV DIS_BUF2+11,#' '
MOV ADDR,#87H
LCALL READ_BYTE
MOV A,DAT
ANL A,#0FH
ADD A,#30H
MOV DIS_BUF2+10,A
MOV A,DAT
SWAP A
ANL A,#0FH
ADD A,#30H
MOV DIS_BUF2+9,A
MOV DIS_BUF2+8,#'-'
MOV ADDR,#89H
LCALL READ_BYTE
MOV A,DAT
ANL A,#0FH
ADD A,#30H
MOV DIS_BUF2+7,A
MOV A,DAT
SWAP A
ANL A,#0FH
ADD A,#30H
MOV DIS_BUF2+6,A
MOV DIS_BUF2+5,#'-'
MOV ADDR,#8DH
LCALL READ_BYTE
MOV A,DAT
ANL A,#0FH
ADD A,#30H
MOV DIS_BUF2+4,A
MOV A,DAT
SWAP A
ANL A,#0FH
ADD A,#30H
MOV DIS_BUF2+3,A
MOV DIS_BUF2+2,YEAR2
MOV DIS_BUF2+1,YEAR1
RET
;--------------------------------------------
SHOW_DAY:
;按DAT里面的数据来选择显示的三个字母
MOV DPTR,#DAY
MOV R4,DAT
CJNE R4,#0,SD_NT
AJMP SD_SHOW ;等于0就跳过进行处理
SD_NT: ;DAT不等于0时
INC DPTR
INC DPTR
INC DPTR
DJNZ R4,SD_NT
SD_SHOW:
CLR A
MOVC A,@A+DPTR
MOV DIS_BUF2+12,A
CLR A
INC DPTR
MOVC A,@A+DPTR
MOV DIS_BUF2+13,A
CLR A
INC DPTR
MOVC A,@A+DPTR
MOV DIS_BUF2+14,A
RET
;***************************************DS1302基本子程序**************************************
;DS1302初始化
;---------------------------------------------------------------------------------------------
INI_DS1302:
;初始化,并利用多字节写入方式写上时间18:00:00[24小时格式],14年5月1日星期4
;并在RAM的前十个单元里面写上0EH
;多字节输入指令0BEH
;秒00H(第一位为暂停位,为1时暂停)
;分00H
;时18H(24小时显示方式)
;日01H
;月05H
;周四:04H
;年14H
;CONTAL:80禁止写入
;可以将上面的数据放在一张表里 DB 0BEH,00H,00H,18H,01H,05H,04H,14H,80H
CLR RST
CLR SCLK
NOP
SETB RST
LCALL SET_TIME_BURST ;多字节方式写入,设置时间
;LCALL SET_TIME_BYTE ;单个字节分别写入
MOV ADDR,#90H
MOV DAT,#0ABH
LCALL WRITE_BYTE
RET
;---------------------------------------
SET_TIME_BYTE:
;秒00H(第一位为暂停位,为1时暂停)
;分00H
;时18H(24小时显示方式)
;日01H
;月05H
;周四:04H
;年14H
;CONTAL:00允许写入
MOV ADDR,#8EH
MOV DAT,#00H
LCALL WRITE_BYTE
MOV ADDR,#80H
MOV DAT,#00H
LCALL WRITE_BYTE
MOV ADDR,#82H
MOV DAT,#00H
LCALL WRITE_BYTE
MOV ADDR,#84H
MOV DAT,#18H
LCALL WRITE_BYTE
RET
;---------------------------------------
SET_TIME_BURST:
MOV ADDR,#8EH ;允许写操作
MOV DAT,#00H
LCALL WRITE_BYTE
SETB RST ;这个是必须的,因为在写字节后是CLR RST
MOV R2,#9 ;必须是大于8的数,因为要连续写入8个字节
MOV DPTR,#SET_TIME
SET_TIME_LP:
CLR A
MOVC A,@A+DPTR
LCALL WRITE_BURST
INC DPTR
DJNZ R2,SET_TIME_LP
CLR RST ;复位,中止多字节传送
RET
;-----------------------------------------
WRITE_BURST:
MOV R3,#8
WB_LP:
RRC A
NOP
MOV IO_DATA,C
NOP
SETB SCLK
NOP
NOP
CLR SCLK
DJNZ R3,WB_LP
RET
;---------------------------------------
WRITE_BYTE:
CLR SCLK
NOP
SETB RST
NOP
MOV A,ADDR
MOV R3,#8
WR_LP:
RRC A
NOP
MOV IO_DATA,C
NOP
SETB SCLK
NOP
NOP
CLR SCLK
DJNZ R3,WR_LP
MOV A,DAT
MOV R3,#8
WR_LP2:
RRC A
NOP
MOV IO_DATA,C
NOP
SETB SCLK
NOP
NOP
CLR SCLK
DJNZ R3,WR_LP2
CLR RST
RET
;-----------------------------------
READ_BYTE:
CLR SCLK
NOP
SETB RST
MOV A,ADDR
MOV R3,#8
RB_LP1:
RRC A
MOV IO_DATA,C
NOP
SETB SCLK
NOP
NOP
CLR SCLK
DJNZ R3,RB_LP1
SETB IO_DATA ;这个是必须的,要不数据读不出来
MOV R3,#8
RB_LP2:
CLR SCLK
NOP
MOV C,IO_DATA
NOP
RRC A
SETB SCLK
NOP
DJNZ R3,RB_LP2
MOV DAT,A
CLR RST
RET
;***************************************LCD屏基本子程序***************************************
;LCD初始化;第二行缓冲区初始化;第一行显示,第二行显示;写指令;写数据;检测;延时
;---------------------------------------------------------------------------------------------
DIS_LCD:
MOV DPTR,#DIS_CHAR
LCALL DIS_LINE1
LCALL SET_BUF2
LCALL DIS_LINE2
RET
;-----------------------------------------------
SET_BUF2:
CLR A
MOV R2,A
MOV DPTR,#CLEAR
MOV R0,#DIS_BUF2
SB_LP:
MOV A,R2
MOVC A,@A+DPTR
MOV @R0,A
INC R0
INC R2
CJNE R2,#16,SB_LP
RET
;-----------------------------------------
DIS_LINE1:
MOV DAT,#80H
LCALL WR_OP
CLR A
MOV R2,A
SL_LP1:
MOV A,R2
MOVC A,@A+DPTR
MOV DAT,A
LCALL WR_DAT
INC R2
CJNE R2,#16,SL_LP1
RET
;--------------------------------------
DIS_LINE2:
MOV DAT,#0C0H
LCALL WR_OP
CLR A
MOV R2,A
MOV R0,#DIS_BUF2
DB_LP2:
MOV A,@R0
MOV DAT,A
LCALL WR_DAT
INC R2
INC R0
CJNE R2,#16,DB_LP2
RET
;--------------------------------------
INI_LCD:
MOV DAT,#38H ;设置显示模式
LCALL WR_OP_NC
MOV R4,#5
LCALL DELAYMS
MOV DAT,#38H
LCALL WR_OP
MOV R4,#5 ;
LCALL DELAYMS
MOV DAT,#08H ;关显示
LCALL WR_OP
MOV DAT,#06H ;设置光标自动加1
LCALL WR_OP
MOV DAT,#0EH ;开显示
LCALL WR_OP
RET
;------------------------------
WR_OP:
LCALL CHECK
WR_OP_NC:
CLR RS
CLR RW
CLR E
MOV P0,DAT
SETB E
LCALL DELAY
CLR E
RET
;------------------------------
WR_DAT:
LCALL CHECK
SETB RS
CLR RW
CLR E
MOV P0,DAT
SETB E
LCALL DELAY
CLR E
RET
;-----------------------------
RD_DAT:
;将数据读出来,并放在DAT里
MOV P0,#0FFH
LCALL CHECK
SETB RS
SETB RW
SETB E
MOV A,P0
MOV DAT,A
CLR E
RET
;-----------------------------
CHECK:
SETB P0.7
CLR RS
SETB RW
SETB E
JB P0.7,$
CLR E
RET
;---------------------------
DELAY:
MOV R3,#3
DJNZ R3,$
RET
;--------------------------
DELAYMS:
MOV R3,#185
DL_LP:
NOP
NOP
NOP
DJNZ R3,DL_LP
DJNZ R4,DELAYMS
RET
;-----------------------------------
DIS_CHAR: DB " WELCOME TO USE "
CLEAR: db " "
SET_TIME: DB 0BEH,00H,00H,18H,01H,05H,04H,14H,80H
TIME_CHAR: DB "Cherish the time"
DATE_CHAR: DB " Today is date: "
DAY: DB "SUN","MON","TUE","WED","THU","FRI","SAT"
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -