⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ds1302_lcd1602.asm

📁 此程序为单片机开发过程中定时芯片ds1302的控制并用lcd显示的程序
💻 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 + -