?? clock - lcd1602.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 + -