;定义 128*64的地址
W_C_GLCD XDATA 0008H ;写控制指令到GLCD
W_D_GLCD XDATA 0009H ;写数据到GLCD
R_B_GLCD XDATA 000AH ;读取忙碌标志和地址
R_D_GLCD XDATA 000BH ;读出GLCD数据
;LCD显示的变量定义
DATA1 DATA 20H ;点阵显示的变量1
N DATA 21H ;行数变量
ADDR DATA 22H ;起始的显示位置
ADDR1 DATA 23H ;起始的显示位置临时变量
N1 DATA 24H ;行数的临时变量
;*************************************************************************
;全速运行程序
ORG 0000H
BEGIN:
MOV SP, #60H ;设置堆栈
CALL INITIAL_GLCD ;调用LCD初试化
LOOP:
CALL GUDINGSHOW0 ;调固定汉字显示
START:
LCALL KEYOP ;调用键值查找子程序,F0=1有键按下,A=键值。
JNB F0, START ;没有键按下输入,重新开始。
LCALL PANJIAN
NEXT: CJNE A,#10H,CONT ;是否是数字键
CONT: JC NUM ;若是数字键,则NUM
MOV DPTR,#JTAB ;若是功能键则送JTAB到DPTR
SUBB A,#10H ;在A中形成JTAB表地址偏移量
RL A
JMP @A+DPTR ;转入相应的功能键分支程序
JTAB: LJMP QUEDING ;转入QUDING功能键处理程序
LJMP CLEAR_GLCD ;转入清屏子程序
QUEDING: JNB 28H.0,YI ;28h.0=0,即第一行数字显示未确定,即转入YI
JNB 28H.1,ER ;28h.1=0,即第二行数字显示未确定,即转入ER
JNB 28H.2,SAN ;28h.2=0,即第三行数字显示未确定,即转入SAN
JNB 28H.3,SI ;28h.3=0,即第四行数字显示未确定,即转入SI
LJMP START ;所有参数设置完毕则回到键盘扫描
YI: SETB 28H.0 ;第一行数字显示标志位置1
MOV R5,#00H ;数字键按下次数累加器清零
LJMP START ;返回键盘扫描
ER: SETB 28H.1 ;第二行数字显示标志位置1
MOV R5,#00H ;数字键按下次数累加器清零
LJMP START ;返回键盘扫描
SAN: SETB 28H.2 ;第三行数字显示标志位置1
MOV R5,#00H ;数字键按下次数累加器清零
LJMP START ;返回键盘扫描
SI: SETB 28H.3 ;第四行数字显示标志位置1
MOV R5,#00H ;数字键按下次数累加器清零
LJMP START ;返回键盘扫描
;**************************************************************************
NUM: INC R5 ;数字键按下次数累加器加1
JNB 28H.0 ,YIHANG ;若28.0=0,则跳转到YIHANG
;若28.0=1,则继续
JNB 28H.1 ,ERHANG ;若28.1=0,则跳转到ERHANG
;若28.1=1,则继续
JNB 28H.2 ,SANHANG ;若28.2=0,则跳转到SANHANG
;若28.2=1,则继续
JNB 28H.3 ,SIHANG ;若28.3=0,则跳转到SIHANG
;若28.3=1,则继续
FAN: RET
YIHANG: MOV 30H,#83H ;第一行数字显示起始位置送入30H
PUSH ACC
MOV A ,30H ;
ADD A ,R5 ;求得此次按键的显示位置
MOV 31H,A ;将求得的值存入31H
POP ACC
LJMP SHUXIAN
ERHANG: MOV 30H,#93H ;第二行数字显示起始位置送入30H
PUSH ACC
MOV A ,30H ;
ADD A ,R5 ;求得此次按键的显示位置
MOV 31H,A ;将求得的值存入31H
POP ACC
LJMP SHUXIAN
SANHANG:MOV 30H,#8BH ;第三行数字显示起始位置送入30H
PUSH ACC
MOV A ,30H ;
ADD A ,R5 ;求得此次按键的显示位置
MOV 31H,A ;将求得的值存入31H
POP ACC
LJMP SHUXIAN
SIHANG:MOV 30H,#8BH ;第四行数字显示起始位置送入30H
PUSH ACC
MOV A ,30H ;
ADD A ,R5 ;求得此次按键的显示位置
MOV 31H,A ;将求得的值存入31H
POP ACC
SHUXIAN:PUSH DPH
PUSH DPL
push acc
push acc
push acc
mov a, 31H ; 送显示地址
LCALL COMMAND_GLcd ;调写命令子程序
pop a
SWAP A ;高低四位元交换
ANL A,#0FH ;留下低四位元
MOV DPTR,#ASCII_CODE ;DPTR 指到 ASCII_CODE
MOVC A,@A+DPTR ;取得 ASCII 码
CALL WRITE_GLCD ;写到 LCD
POP ACC
ANL A,#0FH ;留下低四位元
MOVC A,@A+DPTR ;取得 ASCII 码
CALL WRITE_GLCD ;写到 LCD
POP ACC
POP DPL
POP DPH
LJMP START
ASCII_CODE: DB '0123456789'
;*************************************************************************
KEYOP:
CLR F0 ;f0清0
MOV P1,#00h ;p1清0
ORL P1,#0FH ;把p1低四位置1,(行为高四位,列为低四位)
MOV A,P1 ;有按键则p1低四位不全为1 ,送给a
CJNE A,#0FH,YOUJIAN ;看低4位是否全为1,不相等就有键按下跳到YOUJIAN,相等就无键按下就继续执行
CLR F0
SJMP DONE0
YOUJIAN: SETB F0
DONE0: RET
;***************************************************************************************************************
PANJIAN:LJMP DY12MS
clr RS0 ;改变R0~R7映射区。
clr RS1
MOV R1,#00H ; R1表示第几行, 行值 (以下是进行行扫描)
MOV R3,#04H ; R3表示还没扫描的行数
MOV R0,#0F7H ; 把11110111给r0
XUNHUAN:MOV A,R0 ; 把r0给a
RL A ; 把a左移 变为11101111(使行最低位为0)
MOV R0,A ; 把变了的a还给r0以备扫描下一行用
MOV P1,#0FFH ; 把p1所有位置一
ANL P1,A ; 让p1和a与,使p1的第五位为零,若一行有键按下则对应的列变为0,p1第一位变为0
MOV R2,P1 ;
NOP
NOP
NOP
MOV A,R2 ;
ORL A,#0F0H ; 把行置1
CJNE A,#0FFH,FOU; 如果a等于ff ,表示扫描行无键按下,继续执行。若不等于则有键按下,跳转到fou
INC R1 ; 不在此行则把行数加一
DJNZ R3,XUNHUAN; 所需扫描的行数减一,未扫描完则跳转到xunhuan继续扫描
LJMP DONE ; 扫描完则跳转到exit
FOU: JB ACC.0,FOU1 ; ( 判断在哪一列)看一列是否为1,为0说明在一列,继续执行,为1不在此列跳到fou2
MOV A,#00H ; 把列首键号00给a
AJMP FOU4 ; 跳转到fou4
FOU1: JB ACC.1,FOU2 ;
MOV A,#04H ;
AJMP FOU4 ;
FOU2: JB ACC.2,FOU3 ;
MOV A,#08H ;
AJMP FOU4 ;
FOU3: JB ACC.3,FOU4 ;
MOV A,#0CH ;
FOU4: ADD A,R1 ;
MOV DPTR,#BIAO ;
MOVC A,@A+DPTR ;
MOV 25H,A
MOV R4, A; LJMP指令占3个字节,R3键值乘3
ADD A, R4; 形成转跳地址。
ADD A, R4;
MOV 26H,A
DONE: RET
BIAO: DB 0CH,08H,04H,00H;
DB 0DH,09H,05H,01H
DB 0EH,0AH,06H,02H
DB 0FH,0BH,07H,03H
DY12MS: MOV R7,#18H
DY12MS1:MOV R6,#0FFH
DY12MS2:DJNZ R6,DY12MS2
DJNZ R7,DY12MS1
RET
;*************************************************************************
;设定汉字的显示行: 第一行开始地址为00H~07H
;每行可以显示8个汉字: 第二行开始地址为10H~17H
; 第三行开始地址为08H~0FH
; 第四行开始地址为18H~1FH
;***********************************************