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

📄 12864.asm

📁 单片机12864液晶时钟显示程序
💻 ASM
📖 第 1 页 / 共 2 页
字号:
;*********************************************************************************
X     		EQU  26H        ;LCD 地址变量
;**************变量的定义*****************
RS             BIT      P2.0            ;LCD数据/命令选择端(H/L)
RW             BIT      P2.1          ;LCD读/写选择端(H/L)
EP             BIT      P2.2            ;LCD使能控制
PSB	       EQU	P2.3
RST	       EQU	P2.5
PRE            BIT      P1.4            ;调整键(K1)
ADJ            BIT      P1.5            ;调整键(K2)
COMDAT         EQU P0
LED	       EQU P0.3

YEAR           DATA      18H            ;年,月,日变量
MONTH          DATA      19H
DATE           DATA      1AH
WEEK           DATA      1BH

HOUR           DATA      1CH            ;时,分,秒,百分之一秒变量
MIN            DATA      1DH
SEC            DATA      1EH
SEC100         DATA      1FH

STATE          DATA      23H

LEAP           BIT      STATE.1            ;是否闰年标志1--闰年,0--平年

KEY_S          DATA      24H            ;当前扫描键值
KEY_V          DATA      25H            ;上次扫描键值

DIS_BUF_U0      DATA      26H            ;LCD第一排显示缓冲区
DIS_BUF_U1      DATA      27H
DIS_BUF_U2      DATA      28H
DIS_BUF_U3      DATA      29H
DIS_BUF_U4      DATA      2AH
DIS_BUF_U5      DATA      2BH
DIS_BUF_U6      DATA      2CH
DIS_BUF_U7      DATA      2DH
DIS_BUF_U8      DATA      2EH
DIS_BUF_U9      DATA      2FH
DIS_BUF_U10     DATA      30H
DIS_BUF_U11     DATA      31H
DIS_BUF_U12     DATA      32H
DIS_BUF_U13     DATA      33H
DIS_BUF_U14     DATA      34H
DIS_BUF_U15     DATA      35H

DIS_BUF_L0      DATA      36H            ;LCD第三排显示缓冲区
DIS_BUF_L1      DATA      37H
DIS_BUF_L2      DATA      38H
DIS_BUF_L3      DATA      39H
DIS_BUF_L4      DATA      3AH
DIS_BUF_L5      DATA      3BH
DIS_BUF_L6      DATA      3CH
DIS_BUF_L7      DATA      3DH
DIS_BUF_L8      DATA      3EH
DIS_BUF_L9      DATA      3FH
DIS_BUF_L10     DATA      40H
DIS_BUF_L11     DATA      41H
DIS_BUF_L12     DATA      42H
DIS_BUF_L13     DATA      43H
DIS_BUF_L14     DATA      44H
DIS_BUF_L15     DATA      45H

FLAG            DATA      46H ;1-年,2-月,3-日,4-时,5-分,6-秒,7-退出调整。
DIS_H           DATA      47H
DIS_M           DATA      48H
DIS_S           DATA      49H

;******************初始化***********************
           ORG      0000H
           LJMP     START
           ORG      000BH
	   LJMP     TIMER0

           ORG      0100H
START:     MOV      SP,#60H
           MOV      R0,#18H
           MOV      A,#00H
           CLR 	    LED
MEM_INI:   MOV      @R0,A
           INC      R0
           CJNE     R0,#5FH,MEM_INI
           LCALL    DELAY_5ms      ;初始化LCD
           MOV      R0,#38H            ;设置LCD为16X2显示,5X7点阵,八位数据接口
           LCALL    LCD_WCMD
           LCALL    DELAY_5ms
           MOV      R0,#0CH            ;设置LCD开显示及光标形式(光标不闪烁,不显?-")
           LCALL    LCD_WCMD
           LCALL    DELAY_5ms
           MOV      R0,#06H            ;LCD显示光标移动设置(光标地址指针加1,整屏显示不移动)
           LCALL    LCD_WCMD
           LCALL    DELAY_5ms
           MOV      R0,#01H            ;清除LCD的显示内容
           LCALL    LCD_WCMD
           LCALL    DELAY_5ms
           MOV      YEAR,#00           ;置年初值
           MOV      MONTH,#01      ;置月初值
           MOV      DATE,#01            ;置日初值
           MOV      DIS_H,#12
	   MOV	    HOUR,#12
           LCALL    WEEK_PRO
           LCALL    UPDATE_BUF
           LCALL    DISPLAY_PRO      ;屏显初始化
;*********************主程序*********************
MAIN:      MOV      IE,#8AH            ;CPU开中断,Timer0,Timer1开中断
           MOV      TMOD,#01H      ;Timer0,Timer1工作于模式1, 16位定时方式
           MOV      TH0,#3CH      ;Timer0置50ms定时初值
           MOV      TL0,#0B0H
           SETB     TR0                ;Timer0启动
           MOV      KEY_V,#03H
MAIN_1:    LCALL    KEY_SCAN
           MOV      A,KEY_S
           XRL      A,KEY_V
           JZ       MAIN_1
           LCALL    DELAY_5ms
           LCALL    DELAY_5ms
           LCALL    KEY_SCAN
           MOV      A,KEY_S
           XRL      A,KEY_V
           JZ       MAIN_1
           MOV      KEY_V,KEY_S
           MOV      A,KEY_V
           XRL      A,#01H
           JNZ      MAIN_2
           CLR      TR0            ;进入调整状态,禁止Timer0
           MOV      IE,#00H            ;CPU禁止中断
           LCALL    KEY_PRE_PRO      ;PRE按键按下,调用PRE按键处理程序
           SJMP     MAIN_1
MAIN_2:    MOV      A,KEY_V
           XRL      A,#02H
           JNZ      MAIN_1
           LCALL    KEY_ADJ_PRO      ;ADJ按键按下,调用PRE按键处理程序
           SJMP     MAIN_1
;*******************按键扫描程序******************
KEY_SCAN:  CLR      A
           MOV      P3,#0FFH
           MOV      C,PRE
           MOV      ACC.1,C
           MOV      C,ADJ
           MOV      ACC.0,C
           MOV      KEY_S,A                  ;本次扫描键值存入KEY_S
           RET
;**************PRE按键处理程序*******************
KEY_PRE_PRO: INC      FLAG
           MOV      R4,FLAG
           MOV      R0,#0EH
           LCALL    LCD_WCMD      ;显示光标"_",整个光标不闪烁
KEY_PRE_4: CJNE     R4,#1,KEY_PRE_5
           MOV      R0,#02H
           LCALL    LCD_POS            ;光标置年调整位置
           JMP      KEY_PRE_E
KEY_PRE_5: CJNE     R4,#2, KEY_PRE_6
           MOV      R0,#04H
           LCALL    LCD_POS            ;光标置月调整位置
           JMP      KEY_PRE_E
KEY_PRE_6: CJNE     R4,#3,KEY_PRE_7
           MOV      R0,#06H
           LCALL    LCD_POS            ;光标置日调整位置
           JMP      KEY_PRE_E
KEY_PRE_7: CJNE     R4,#4,KEY_PRE_8
           MOV      R0,#14H
           LCALL    LCD_POS            ;光标置时调整位置
           JMP      KEY_PRE_E
KEY_PRE_8: CJNE     R4,#5,KEY_PRE_9
           MOV      R0,#15H
           LCALL    LCD_POS            ;光标置分调整位置
           JMP      KEY_PRE_E
KEY_PRE_9: CJNE     R4,#6,KEY_PRE_10
           MOV      R0,#17H
           LCALL    LCD_POS            ;光标置秒调整位置
           JMP      KEY_PRE_E
KEY_PRE_10:MOV      FLAG,#0            ;FLAG到7,就清零
           MOV      R0,#0CH
           LCALL    LCD_WCMD      ;设置LCD开显示及光标不闪烁,不显示"-"
;           MOV      R0,#01H
 ;          LCALL    LCD_WCMD      ;清除LCD的显示内容
           MOV      IE,#8AH            ;CPU开中断,TIMER0,TIMER1开中断
           SETB     TR0            ;启动TIMER0
KEY_PRE_E: RET
;**************ADJ按键处理程序*******************
KEY_ADJ_PRO:MOV      R0,#0CH
     	    LCALL      LCD_WCMD      ;设置LCD开显示及光标不闪烁,不显示"-"
            MOV      R5,FLAG
KEY_ADJ_4: CJNE      R5,#1,KEY_ADJ_5            ;FLAG=5,调整年
KEY_ADJ_40:INC       YEAR
           MOV       A,YEAR
           CJNE      A,#100,KEY_ADJ_4_1
           MOV       YEAR,#0
KEY_ADJ_4_1: LCALL   WEEK_PRO
           LCALL     UPDATE_BUF
           LCALL     DISPLAY_PRO
           MOV       R0,#05H
           LCALL     LCD_POS
           LCALL      DELAY_200ms
	        JNB			ADJ,KEY_ADJ_40
			  JMP       KEY_ADJ_E
KEY_ADJ_5: CJNE      R5,#2,KEY_ADJ_6            ;FLAG=6,调整月
KEY_ADJ_50:INC       MONTH
           MOV       A,MONTH
           CJNE      A,#13,KEY_ADJ_5_1
           MOV       MONTH,#1
KEY_ADJ_5_1: LCALL   WEEK_PRO
           LCALL     UPDATE_BUF
           LCALL     DISPLAY_PRO
           MOV       R0,#08H
           LCALL     LCD_POS
           LCALL      DELAY_200ms
	        JNB			ADJ,KEY_ADJ_50
			  JMP       KEY_ADJ_E
KEY_ADJ_6: CJNE      R5,#3,KEY_ADJ_7            ;FLAG=7,调整日
KEY_ADJ_60:INC       DATE
           MOV       A,MONTH
           XRL       A,#2
           JNZ       KEY_ADJ_6_2            ;不是二月跳转
           MOV       A,DATE                  ;
           MOV       C,LEAP                  ;判断是否闰年
           JC        KEY_ADJ_6_1
           XRL       A,#29                  ;平年二月日期28天
           JNZ       KEY_ADJ_6_5
           JMP       KEY_ADJ_6_4
KEY_ADJ_6_1: XRL     A,#30                  ;闰年二月日期29天
           JNZ       KEY_ADJ_6_5
           JMP       KEY_ADJ_6_4            ;跳转到月处理
KEY_ADJ_6_2: MOV      A,MONTH
           XRL       A,#4
           JZ        KEY_ADJ_6_3
           MOV       A,MONTH
           XRL       A,#6
           JZ        KEY_ADJ_6_3
           MOV       A,MONTH
           XRL       A,#9
           JZ        KEY_ADJ_6_3
           MOV       A,MONTH
           XRL       A,#11
           JZ        KEY_ADJ_6_3
           MOV       A,DATE
           XRL       A,#32                  ;大月日期31天
           JNZ       KEY_ADJ_6_5
           JMP       KEY_ADJ_6_4
KEY_ADJ_6_3: MOV     A,DATE
           XRL       A,#31                  ;小月日期30天
           JNZ       KEY_ADJ_6_5
KEY_ADJ_6_4: MOV     DATE,#1
KEY_ADJ_6_5: LCALL   WEEK_PRO
           LCALL     UPDATE_BUF
           LCALL     DISPLAY_PRO
           MOV       R0,#0BH
           LCALL     LCD_POS
           LCALL      DELAY_200ms
	        JNB			ADJ,KEY_ADJ_60
			  JMP       KEY_ADJ_E
KEY_ADJ_7:  CJNE     R5,#4,KEY_ADJ_8            ;FLAG=8,调整时
KEY_ADJ_70:INC       HOUR
           MOV       A,HOUR
           CJNE      A,#24,KEY_ADJ_7_1
           MOV       HOUR,#0
KEY_ADJ_7_1: MOV     DIS_H,HOUR
           LCALL     UPDATE_BUF
           LCALL     DISPLAY_PRO
           MOV       R0,#49H
           LCALL     LCD_POS
           LCALL      DELAY_200ms
	        JNB			ADJ,KEY_ADJ_70
			  JMP       KEY_ADJ_E
KEY_ADJ_8: CJNE      R5,#5,KEY_ADJ_9            ;FLAG=9,调整分
KEY_ADJ_80:           INC       MIN
           MOV       A,MIN
           CJNE      A,#60,KEY_ADJ_8_1
           MOV       MIN,#0
KEY_ADJ_8_1: MOV     DIS_M,MIN
           LCALL     UPDATE_BUF
           LCALL     DISPLAY_PRO
           MOV       R0,#4CH
           LCALL     LCD_POS
           LCALL      DELAY_200ms
	        JNB			ADJ,KEY_ADJ_80
			  JMP       KEY_ADJ_E
KEY_ADJ_9: CJNE      R5,#6,KEY_ADJ_E      ;FLAG=10,调整秒
KEY_ADJ_90:INC       SEC
           MOV       A,SEC
           CJNE      A,#60,KEY_ADJ_9_1
           MOV       SEC,#0
KEY_ADJ_9_1: MOV     DIS_S,SEC
           LCALL     UPDATE_BUF
           LCALL     DISPLAY_PRO
           MOV       R0,#4FH
           LCALL     LCD_POS
           LCALL      DELAY_200ms
	        JNB			ADJ,KEY_ADJ_90
KEY_ADJ_E: RET
;***************Timer0定时中断程序*****************
TIMER0:    MOV      TH0,#3CH
           MOV      TL0,#0B0H 
           INC      SEC100	
 	   MOV      A,SEC100
           CJNE     A,#20,TIMER0_E
           MOV      SEC100,#0
           LCALL    TIME_PRO
TIMER0_2:  MOV      DIS_H,HOUR
           MOV      DIS_M,MIN
           MOV      DIS_S,SEC
           LCALL    UPDATE_BUF
           LCALL    DISPLAY_PRO
TIMER0_E:  RETI
;**************时间日期处理函数******************
TIME_PRO:  INC      SEC                  ;秒处理
           MOV      A,SEC
           CJNE     A,#60,TIME_PRO_e
           MOV      SEC,#0
           INC      MIN                  ;分处理
           MOV      A,MIN
           CJNE     A,#60,TIME_PRO_e
           MOV      MIN,#0
           INC      HOUR                  ;时处理
           MOV      A,HOUR
           CJNE     A,#24,TIME_PRO_e
           MOV      HOUR,#0
           INC      DATE                  ;日处理(日处理要考虑是否闰年,大月,小月)
           MOV      A,MONTH
           XRL      A,#2
           JNZ      TIME_PRO_D2            ;不是二月,转TIME_PRO_D2
           MOV      A,DATE                  ;
           MOV      C,LEAP                  ;判断是否闰年
           JC       TIME_PRO_D1
           XRL      A,#29                  ;平年二月日期28天
           JNZ      TIME_PRO_W
           SJMP     TIME_PRO_M            ;跳转到月处理
TIME_PRO_D1:XRL     A,#30                  ;闰年二月日期29天
           JNZ      TIME_PRO_W
           SJMP     TIME_PRO_M            ;跳转到月处理
TIME_PRO_D2:MOV     A,MONTH
           XRL      A,#4
           JZ       TIME_PRO_D3
           MOV      A,MONTH
           XRL      A,#6
           JZ       TIME_PRO_D3
           MOV      A,MONTH
           XRL      A,#9
           JZ       TIME_PRO_D3
           MOV      A,MONTH
           XRL      A,#11
           JZ       TIME_PRO_D3
           MOV      A,DATE
           XRL      A,#32                  ;大月日期31天
           JNZ      TIME_PRO_W
           SJMP     TIME_PRO_M            ;跳转到月处理
TIME_PRO_D3:MOV     A,DATE
           XRL      A,#31                  ;小月日期30天
           JNZ      TIME_PRO_W
TIME_PRO_M:MOV      DATE,#1
           INC      MONTH                  ;月处理
           MOV      A,MONTH
           CJNE     A,#13,TIME_PRO_W
           MOV      MONTH,#1
           INC      YEAR                  ;年处理
           MOV      A,YEAR
           CJNE     A,#100,TIME_PRO_W
           MOV      YEAR,#0
TIME_PRO_W:LCALL    WEEK_PRO            ;星期处理
TIME_PRO_E:RET
;**********星期自动运算函数*********************
;星期运算常数W(5或6)
;闰年的数目L(0--99年:L=YEAR/4 整除)
;年数YEAR
;月参变数MONTH_TAB(0,3,3,6,1,4,6,2,5,0,3,5)
;日期DATE
;星期数=(W+L+YEAR+MONTH_TAB+DATE)%7 (求余)
WEEK_PRO:  MOV      A,MONTH                  ;确定星期运算常数W
           XRL      A,#1
           JZ       WEEK_PRO_1
           MOV      A,MONTH
           XRL      A,#2
           JZ       WEEK_PRO_1
           SJMP     WEEK_PRO_2
WEEK_PRO_1:LCALL    LEAP_PRO
           MOV      C,LEAP
           JNC      WEEK_PRO_2
           MOV      R3,#5
           SJMP     WEEK_PRO_3
WEEK_PRO_2:MOV      R3,#6
WEEK_PRO_3:MOV      A,YEAR                  ;计算闰年的数目L
           MOV      B,#4
           DIV      AB
           ADD      A,R3                  ;W+L
           MOV      R3,A
           MOV      A,YEAR
           ADD      A,R3                  ;(W+L)+YEAR
           MOV      R3,A
           MOV      DPTR,#MONTH_TAB
           MOV      A,MONTH
           MOVC     A,@A+DPTR
           ADD      A,R3                  ;(W+L+YEAR)+MONTH_TAB
           MOV      R3,A
           MOV      A,DATE
           ADD      A,R3                  ;(W+L+YEAR+MONTH_TAB+DATE)
           MOV      B,#7
           DIV      AB                  ;余数即为星期数
           MOV      WEEK,B
           RET
;**********闰年的判断函数*********************
;闰年的条件:年(YEAR)能被4整除、但不能被100整除;或者被400整除。
;如果我们只考虑(00--99),则只需考虑年(YEAR)能被4整除即可。
LEAP_PRO:  MOV      A,YEAR
           MOV      B,#4
           DIV      AB
           MOV      A,B
           JZ       LEAP_PRO_1      ;能被4整除
           CLR      LEAP            ;平年,清零LEAP
           LJMP     LEAP_PRO_E
LEAP_PRO_1:SETB     LEAP            ;闰年,置位LEAP
LEAP_PRO_E:RET
;**********更新显示缓冲区********************
;入口R1,
UPDATE_BUF:MOV      DIS_BUF_U0,#20H;空格
           MOV      DIS_BUF_U1,#20H;空格
           MOV      DIS_BUF_U2,#32H      ;"2"
           MOV      DIS_BUF_U3,#30H      ;"0"
           MOV      A,YEAR            ;更新年数据
           MOV      B,#10
           DIV      AB
           ADD      A,#48            ;二进制转换为ASCMA码
           MOV      DIS_BUF_U4,A
           MOV      A,B
           ADD      A,#48
           MOV      DIS_BUF_U5,A
           MOV      DIS_BUF_U6,#0c4H      ;"-"
           MOV      DIS_BUF_U7,#0eaH;"-"
           MOV      A,MONTH            ;更新月数据
           MOV      B,#10
           DIV      AB
           ADD      A,#48
           MOV      DIS_BUF_U8,A
           MOV      A,B
           ADD      A,#48
           MOV      DIS_BUF_U9,A
           MOV      DIS_BUF_U10,#0d4H      ;"-"
           MOV      DIS_BUF_U11,#0c2H
           MOV      A,DATE            ;更新日数据
           MOV      B,#10
           DIV      AB
           ADD      A,#48
           MOV      DIS_BUF_U12,A
           MOV      A,B
           ADD      A,#48
           MOV      DIS_BUF_U13,A
           MOV      DIS_BUF_U14,#0c8H;空格
           MOV      DIS_BUF_U15,#0d5H;空格

           MOV      DIS_BUF_L0,#0d0h
           MOV      DIS_BUF_L1,#0c7h
           MOV      DIS_BUF_L2,#0c6h
           MOV      DIS_BUF_L3,#0dah
           MOV      A,week
           CJNE     A,#1,week1         ;1显示星期一
           MOV      DIS_BUF_L4,#0d2h
           MOV      DIS_BUF_L5,#0bbh
           SJMP     UPDATE_BUF_2
     week1:CJNE     A,#2,week2			;2显示星期二
           MOV      DIS_BUF_L4,#0b6h
           MOV      DIS_BUF_L5,#0feh
           SJMP     UPDATE_BUF_2
     week2:CJNE     A,#3,week3			;3显示星期三
           MOV      DIS_BUF_L4,#0c8h
           MOV      DIS_BUF_L5,#0fdh
           SJMP     UPDATE_BUF_2
     week3:CJNE     A,#4,week4			;4显示星期四
           MOV      DIS_BUF_L4,#0cbh
           MOV      DIS_BUF_L5,#0c4h
           SJMP     UPDATE_BUF_2
     week4:CJNE     A,#5,week5			;5显示星期五
           MOV      DIS_BUF_L4,#0ceh
           MOV      DIS_BUF_L5,#0e5h
           SJMP  	  UPDATE_BUF_2
     week5:CJNE     A,#6,week6			;6显示星期六
           MOV      DIS_BUF_L4,#0c1h
           MOV      DIS_BUF_L5,#0f9h
           SJMP     UPDATE_BUF_2
     week6:MOV      DIS_BUF_L4,#0c8h	;7显示星期日
           MOV      DIS_BUF_L5,#0d5h
           MOV      DIS_BUF_L6,#' '      ;空格

UPDATE_BUF_2:MOV 	  DIS_BUF_L7,#' '      ;空格
           MOV      A,DIS_H
           MOV      B,#10
           DIV      AB
           ADD      A,#48
           MOV      DIS_BUF_L8,A
           MOV      A,B
           ADD      A,#48
           MOV      DIS_BUF_L9,A
           MOV      DIS_BUF_L10,#3AH;":"
           MOV      A,DIS_M
           MOV      B,#10
           DIV      AB

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -