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

📄 clock - lcd1602.asm

📁 1602显示电子时钟的51代码。包括C语言和汇编语言两种语言。
💻 ASM
字号:
;********************************************************************
;*                                                                  *
;* ME500单片机开发系统演示程序 -   时钟                             *
;*                                                                  *
;* LCD1602显示                                                      *
;*                                                                  *
;* 版本: V1.0 (2006/11/20)                                         *
;* 作者: gguoqing (Email: gguoqing@willar.com)                     *
;* 网站: www.willar.com(伟纳电子)   www.mcusj.com(伟纳单片机世界)  *
;* 邮箱: support@willar.com                                        * 
;*                                                                  *
;*【版权】Copyright(C)伟纳电子 www.willar.com  All Rights Reserved  *
;*【声明】此程序仅用于学习与参考,引用请注明版权和作者信息!        *
;*                                                                  *
;*******************************************************************/
         	 
          HOUR    EQU  30H      ;时计数
          MIN     EQU  31H      ;分计数
          SEC     EQU  32H      ;秒计数
          MSEC    EQU  33H      ;50MS计数
       
          LCD_X   EQU  35H      ;LCD 地址变量

          K1      BIT  P1.4     ;健定义
          K2      BIT  P1.5
          K3      BIT  P1.6
          K4      BIT  P1.7
          
	  SET_DR  BIT  20H.0

          LCD_RS  BIT  P2.0     ;LCD 控制管脚定义
          LCD_RW  BIT  P2.1
          LCD_EN  BIT  P2.2

          SPK     BIT  P3.7     ;蜂鸣器

;**********************************************************

          ORG   0000H
          JMP   MAIN
          ORG   000BH
          JMP   T0_INT
	  ORG   0030H

;**********************************************************

; 主程序

;**********************************************************
MAIN:          
	  SETB  SET_DR      
          CALL  SET_LCD       ;初始化LCD

	  MOV  R5,#250        ;延时4S
          CALL  DELAY
	  MOV  R5,#150
          CALL  DELAY

          CALL  BEEP          ;蜂鸣器响一声
          CALL  INIT          ;初始化变量
	  CALL  MENU1	  
          CALL  MENU2
LOOP:
	  CALL  CONV
          JB     K1,LOOP      ;K1设定时间健
          CALL   BEEP
          JNB    K1,$

          CALL  MENU3     ;显示菜单1  
          CALL  SET_TIME     ;设置目前时间
          CALL  MENU1     ;显示菜单3
          JMP  LOOP
          RET

;**********************************************************

;  LCD 初始化显示 
 
;**********************************************************
SET_LCD:                    
          CALL  INIT_LCD     ;初始化 LCD
          MOV  R5,#10
          CALL  DELAY
          MOV  DPTR,#LMESS1  ;指针指到显示消息1
	  CALL  W_STRING1

          MOV  DPTR,#LMESS2  ;指针指到显示消息2
          CALL  W_STRING2
          RET

LMESS1:   DB  "   WELCOME TO   ",0  ;LCD 第一行显示消息
LMESS2:   DB  " WWW.WILLAR.COM ",0  ;LCD 第二行显示消息

;**********************************************************

; 初始化变量 

;**********************************************************
INIT:   
         MOV  MSEC,#0          
         MOV  SEC,#0
         MOV  MIN,#59
         MOV  HOUR,#23
                       
         MOV  TMOD,#01H    ;设置定时器0 工作模式为模式1
         MOV  IE,  #82H    ;启用定时器0 中断产生
         MOV  TL0,#00H
         MOV  TH0,#4CH
         SETB  TR0         ;启动中断
         RET

;**********************************************************

; 定时器0 计时中断子程序
; 每隔50MS中断一次

;**********************************************************
T0_INT:
         PUSH  ACC           
         MOV  TL0,#00H
         MOV  TH0,#4CH       ;50ms定时常数

         INC  MSEC
         MOV  A,MSEC         ;50MS 计数值加1
         CJNE  A,#20,T_END
         MOV  MSEC,#0
         INC  SEC            ;秒加1
         MOV  A,SEC
         CJNE  A,#60,T_END
         INC  MIN            ;分加1
         MOV  SEC,#0
         MOV  A,MIN
         CJNE  A,#60,T_END
         INC  HOUR           ;时加1
         MOV  MIN,#0
         MOV  A,HOUR
         CJNE  A,#24,T_END
         MOV  SEC,#0         ;秒、分、时单元清0
         MOV  MIN,#0
         MOV  HOUR,#0
T_END:     
         POP  ACC
         RETI

;**********************************************************

; 时间设定子程序
; K1: UP-DOWN K2: HH  K3: MM  K4: OK

;**********************************************************
SET_TIME:
         CLR  TR0           ;终止中断
	 SETB  SET_DR
         MOV   SEC,#0
   S0:   
         JB  K2,S1          ;小时调整
         CALL  BEEP
    
         JNB  SET_DR,S01    
         INC  HOUR
         MOV  A,HOUR
         CJNE  A,#24,S02
         MOV  HOUR,#0
	 JMP  S02
   S01:
         DEC  HOUR
         MOV  A,HOUR
         CJNE  A,#0FFH,S02           
         MOV  HOUR,#23
   S02:  
         CALL  CONV         ;转换显示数据
         JMP  S0
   S1:   
         JB  K3,S2          ;分钟调整
         CALL  BEEP
	 JNB  SET_DR,S11 
         INC  MIN
         MOV  A,MIN
         CJNE  A,#60,S12
         MOV  MIN,#0
         JMP  S12
   S11:
         DEC  MIN
	 MOV  A,MIN
	 CJNE  A,#0FFH,S12
         MOV  MIN,#59

  S12:   
         CALL  CONV          ;转换显示数据
         JMP  S0
  S2:    
         JB  K1,S3
         CALL  BEEP
	 JNB  K1,$          ;等待健释放
	 CPL  SET_DR
  S3:
         JB  K4,S0
         CALL  BEEP
         JNB  K4,$
	 SETB  SET_DR
         SETB  TR0          ;启动中断
         RET

;==================================================

; 在 LCD 第二行的指定位置显示数字

;==================================================
SHOW_DIG2:                ;在 LCD 的第二行显示数字
          MOV  B,#10
          DIV  AB
          ADD  A,#30H
          PUSH  B
          MOV  B,LCD_X
          CALL  LCDP2
          POP  B
          MOV  A,B
          ADD  A,#30H
          INC  LCD_X
          MOV  B,LCD_X
          CALL  LCDP2
          RET
;**********************************************************

;转换为 ASCII 码并且显示

;**********************************************************
CONV:
          MOV  A,HOUR        ;加载小时数据
          MOV  LCD_X,#7          ;设置位置
          CALL  SHOW_DIG2    ;显示数据
          INC  LCD_X             ;
          MOV  A,#':'        ;
          MOV  B,LCD_X           ;
          CALL  LCDP2        ;
          MOV  A,MIN         ;加载分钟数据
          INC  LCD_X             ;设置位置
          CALL  SHOW_DIG2    ;显示数据
          INC  LCD_X             ;
          MOV  A,#':'        ;
          MOV  B,LCD_X           ;
          CALL  LCDP2        ;
          MOV  A,SEC         ;加载秒数数据
          INC  LCD_X             ;设置位置
          CALL  SHOW_DIG2    ;显示数据
          RET

;**********************************************************

; LCD 初始化子程序

;**********************************************************
INIT_LCD:                   
          MOV  A,#38H       ;双列显示,字形5*7点阵
          CALL  WCOM
          CALL  DELAY1
          MOV  A,#38H       ;双列显示,字形5*7点阵
          CALL  WCOM
          CALL  DELAY1
          MOV  A,#38H       ;双列显示,字形5*7点阵
          CALL  WCOM
          CALL  DELAY1
         
          MOV  A,#0CH        ;开显示,不显示光标。
          CALL  WCOM        
          CALL  DELAY1
          MOV  A,#06H        
          CALL  WCOM       
          CALL  DELAY1
          MOV  A,#01H        ;清除 LCD 显示屏
          CALL  WCOM        
          CALL  DELAY1
          RET

;**********************************************************

; 清除LCD的第一行字符

;**********************************************************
CLR_LINE1:                   
          MOV  A,#80H        ;设置 LCD 的第一行地址
          CALL  WCOM         ;
          MOV  R0,#24        ;设置计数值
    C1:  
          MOV  A,#' '        ;载入空格符至LCD
          CALL  WDATA        ;输出字符至LCD
          DJNZ  R0,C1        ;计数结束
          RET

;**********************************************************

; 在LCD的第一行或第二行显示字符

;**********************************************************
LCD_PRINT:       

          CJNE  A,#1,LINE2  ;判断是否为第一行
  LINE1:  MOV  A,#80H       ;设置 LCD 的第一行地址
          CALL  WCOM        ;写入命令
          CALL  CLR_LINE    ;清除该行字符数据
          MOV  A,#80H       ;设置 LCD 的第一行地址
          CALL  WCOM        ;写入命令
          JMP  FILL

  LINE2:  MOV  A,#0C0H      ;设置 LCD 的第二行地址
          CALL  WCOM        ;写入命令
          CALL  CLR_LINE    ;清除该行字符数据
          MOV  A,#0C0H      ;设置 LCD 的第二行地址
          CALL  WCOM
  FILL:   CLR  A            ;填入字符
          MOVC  A,@A+DPTR   ;由字符区取出字符
          CJNE  A,#0,LC1    ;判断是否为结束码
          RET
  LC1:    CALL  WDATA       ;写入数据
          INC  DPTR         ;指针加1
          JMP  FILL         ;继续填入字符
          RET

CLR_LINE:                   ;清除该行 LCD 的字符
          MOV  R0,#24
   CL1:   MOV  A,#' '
          CALL  WDATA
          DJNZ  R0,CL1
          RET

;**********************************************************

; 写字符串子程序

;**********************************************************
W_STRING1:
         MOV  A,#80H       ;设置 LCD 的第一行地址
         CALL  WCOM        ;写入命令
	 CALL  FILL_CHAR
	 RET

W_STRING2:
         MOV  A,#0C0H       ;设置 LCD 的第二行地址
         CALL  WCOM        ;写入命令
	 CALL  FILL_CHAR
	 RET

;**********************************************************

; 写入字符子程序

;**********************************************************
FILL_CHAR:   
         CLR  A                  ;填入字符
         MOVC  A,@A+DPTR         ;由字符区取出字符
         CJNE  A,#0,F_CHAR       ;判断是否为结束码
         RET
F_CHAR: 
         CALL  WDATA             ;写入数据
	 MOV  R5,#15             ;延时,形成逐字显示的效果
	 CALL DELAY
         INC  DPTR               ;指针加1
         JMP  FILL_CHAR          ;继续填入字符
         RET

;**********************************************************

;LCD1602写命令子程序
;LCD_RS=L,LCD_RW=L,D0-D7=指令码,E=高脉冲

;**********************************************************
WCOM:
          MOV   P0,A       ;写入指令
          CLR   LCD_RS      
          CLR   LCD_RW
          SETB  LCD_EN
          CALL  DE
          CLR   LCD_EN
          CALL  DE
          RET

;**********************************************************

;LCD1602写数据子程序
;LCD_RS=H,LCD_RW=L,D0-D7=数据码,E=高脉冲

;**********************************************************
WDATA:
          MOV  P0,A       ;写入数据
          SETB  LCD_RS    
          CLR   LCD_RW
          SETB  LCD_EN
          CALL  DE
          CLR   LCD_EN
          CALL  DE
          RET
DE:       
          MOV  R7,#250
          DJNZ  R7,$
          RET

;**********************************************************

;在LCD第一行显示数据  A=ASC DATA, B=LINE POSITION

;**********************************************************
LCDP1:                    ;在LCD的第一行显示字符
         PUSH  ACC        ;
         MOV  A,B         ;设置显示地址
         ADD  A,#80H      ;设置LCD的第一行地址
         CALL  WCOM       ;写入命令
         POP  ACC         ;由堆栈取出A
         CALL  WDATA      ;写入数据
         RET

;**********************************************************

;在LCD第二行显示数据  A=ASC DATA, B=LINE POSITION

;**********************************************************
LCDP2:                   
         PUSH  ACC        ;
         MOV  A,B         ;设置显示地址
         ADD  A,#0C0H     ;设置LCD的第二行地址
         CALL  WCOM       ;写入命令
         POP  ACC         ;由堆栈取出A
         CALL  WDATA      ;写入数据
         RET
;**********************************************************

; 延时10MS子程序

;**********************************************************
DELAY:                    
         MOV  R6,#50
DEL1:   
         MOV  R7,#100
         DJNZ  R7,$
         DJNZ  R6,DEL1
         DJNZ  R5,DELAY
         RET

;**********************************************************

; 延时5MS子程序

;**********************************************************
DELAY1:                    
         MOV  R6,#25
DEL2:   
         MOV  R7,#100
         DJNZ  R7,$
         DJNZ  R6,DEL2
         RET

;**********************************************************

; 驱动蜂鸣器子程序

;**********************************************************
BEEP:
         MOV  R6,#150
  B2:    
         CALL  DE1
         CPL  SPK
         DJNZ  R6,B2
         MOV  R5,#25
         CALL  DELAY
         RET
DE1:   
         MOV  R7,#200
DE2:    
         NOP	
         DJNZ  R7,DE2
         RET

;**********************************************************

; 显示菜单子程序

;**********************************************************

BEIJNG:  DB  "  BEIJING TIME  ",0
TIME:    DB  " TIME:          ",0
STIME:   DB  " RESET REALTIME ",0

MENU1:                      
         MOV  DPTR,#BEIJNG
         MOV  A,#1
         CALL  LCD_PRINT
         RET
MENU2:                      
         MOV  DPTR,#TIME
         MOV  A,#2
         CALL  LCD_PRINT
         RET
MENU3:                      
         MOV  DPTR,#STIME
         MOV  A,#1
         CALL  LCD_PRINT
         RET

;**********************************************************
         END

⌨️ 快捷键说明

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