键盘扫描程序段 OUTBIT equ 08002h ; 列地址 IN equ 08001h ; 行地址
Delay: ; 延时子程序 mov r7, #0 DelayLoop: djnz r7, DelayLoop djnz r6, DelayLoop ret TestKey: mov dptr, #OUTBIT mov a, #0 movx @dptr, a ; 输出线置为0 mov dptr, #IN movx a, @dptr ; 读入键状态 cpl a anl a, #0fh ; 高四位不用 ret KeyTable: ; 键码定义
db 16h, 15h, 14h, 0ffh db 13h, 12h, 11h, 10h db 0dh, 0ch, 0bh, 0ah db 0eh, 03h, 06h, 09h db 0fh, 02h, 05h, 08h db 00h, 01h, 04h, 07h GetKey: mov dptr, #OUTBIT mov P2, dph mov r0, #Low(IN) mov r1, #00100000b mov r2, #6 KLoop: mov a, r1 ; 找出键所在列 cpl a movx @dptr, a cpl a rr a mov r1, a ; 下一列 movx a, @r0 cpl a anl a, #0fh jnz Goon1 ; 该列有键入 djnz r2, KLoop mov r2, #0ffh ; 没有键按下, 返回 0ffh sjmp Exit Goon1: mov r1, a ; 键值 = 列 X 4 + 行 mov a, r2 dec a rl a rl a mov r2, a ; r2 = (r2-1)*4 mov a, r1 ; r1 中为读入的行值 mov r1, #4 LoopC: rrc a ; 移位找出所在行 jc Exit inc r2 ; r2 = r2+ 行值 djnz r1, LoopC Exit: mov a, r2 ; 取出键码 mov dptr, #KeyTable movc a, @a+dptr mov r2, a WaitRelease: mov dptr, #OUTBIT ; 等键释放 clr a movx @dptr, a mov r6, #10 call Delay call TestKey jnz WaitRelease mov a, r2 ret
OUTBIT equ 09002h ; 列地址 IN equ 09001h ; 行地址 CWADD1 EQU 8000H ;写指令代码地址(E1) DWADD1 EQU 8001H ;写显示数据地址(E1) CRADD1 EQU 8002H ;读状态字地址(E1) DRADD1 EQU 8003H ;读显示数据地址(E1) CWADD2 EQU 8004H ;写指令代码地址(E2) DWADD2 EQU 8005H ;写显示数进地址(E2) CRADD2 EQU 8006H ;读状态字地址(E2) DRADD2 EQU 8007H ;读显示数据地址(E2) KEY_VALUE EQU 29H ;键值 PD1 EQU 28H ;122/2 分成左右两半屏 122x32 COLUMN EQU 27H ; PAGE_SED EQU 26H ;页地址寄存器 D1,DO:页地址 CODE_SED EQU 25H ;字符代码寄存器 COUNT EQU 24H ;计数器 DIR equ 23h CTEMP EQU 22H COM EQU 21H ;指令寄存器 DAT EQU 20H ;数据寄存器
ORG 0000H LJMP start
start: mov sp,#60h key_loop: lcall testkey jz key_loop lcall getkey cjne a,#10h,no_show1 no_show1: jnc no_show2 mov key_value,a lcall exe_key no_show2: sjmp key_loop
Delay: ; 延时子程序 mov r7, #0 DelayLoop: djnz r7, DelayLoop djnz r6, DelayLoop ret
TestKey: mov dptr, #OUTBIT mov a, #0 movx @dptr, a ; 输出线置为0 mov dptr, #IN movx a, @dptr ; 读入键状态 cpl a anl a, #0fh ; 高四位不用 ret KeyTable: ; 键码定义
db 16h, 15h, 14h, 0ffh
db 13h, 12h, 11h, 10h
db 0dh, 0ch, 0bh, 0ah
db 0eh, 03h, 06h, 09h
db 0fh, 02h, 05h, 08h
db 00h, 01h, 04h, 07h GetKey: mov dptr, #OUTBIT mov P2, dph mov r0, #Low(IN) mov r1, #00100000b mov r2, #6 KLoop: mov a, r1 ; 找出键所在列 cpl a movx @dptr, a cpl a rr a mov r1, a ; 下一列 movx a, @r0 cpl a anl a, #0fh jnz Goon1 ; 该列有键入 djnz r2, KLoop mov r2, #0ffh ; 没有键按下, 返回 0ffh sjmp Exit Goon1: mov r1, a ; 键值 = 列 X 4 + 行 mov a, r2 dec a rl a rl a mov r2, a ; r2 = (r2-1)*4 mov a, r1 ; r1 中为读入的行值 mov r1, #4 LoopC: rrc a ; 移位找出所在行 jc Exit inc r2 ; r2 = r2+ 行值 djnz r1, LoopC Exit: mov a, r2 ; 取出键码 mov dptr, #KeyTable movc a, @a+dptr mov r2, a WaitRelease: mov dptr, #OUTBIT ; 等键释放 clr a movx @dptr, a mov r6, #10 call Delay call TestKey jnz WaitRelease mov a, r2 ret ; 8*16点阵字符显示程序段 EXE_KEY: LCALL INIT LCALL CLEAR MOV CTEMP,#0 MOV DIR,#0 MOV PAGE_SED,#00H MOV COLUMN,#0 MOV CODE_SED,KEY_VALUE LCALL WRI_EN816 RET
;--------------------------------------- ; 初始化程序 INIT: MOV COM, #0E2H ;复位 LCALL PR0 LCALL PR3 MOV COM, #0A4H ;关闭休闭状态 LCALL PR0 LCALL PR3 MOV COM, #0A9H ;设置 1/32 占空比 LCALL PR0 LCALL PR3 MOV COM, #0A0H ;正向排序设置 LCALL PR0 LCALL PR3 MOV COM, #0C0H ;设置显示起始行为第一行 LCALL PR0 LCALL PR3 MOV COM, #0AFH ;开显示设置 LCALL PR0 LCALL PR3 RET ;------------------------------------------------ ; 清屏 CLEAR: MOV R4,#00H ;页面地址暂存器设置 CLEAR1: MOV A,R4 ;取页地址值 ORL A,#0B8H ;"或"页面地址设置代码 MOV COM,A ;页面地址设置 LCALL PR0 LCALL PR3 MOV COM,#00H ;列地址设置为"0" LCALL PR0 LCALL PR3 MOV R3,#50H ;一页清 80个字节 CLEAR2: MOV DAT,#00H ;显示数据为"0" LCALL PR1 LCALL PR4 DJNZ R3,CLEAR2 ;页内字节清零循环 INC R4 ;页地址暂存器加一 CJNE R4,#04H,CLEAR1;RAM 区清零循环 RET ;----------------------------------- ;1.写指令代码子程序(E1) PR0: PUSH DPL PUSH DPH MOV DPTR,#CRADD1 ;设置读状态字地址 PR01: MOVX A,@DPTR ;读状态字 JB ACC.7,PR01 ;判"忙"标志为句"0",否再读 MOV DPTR,#CWADD1 ;设置写指令代码地址 MOV A,COM ;取指令代码 MOVX @DPTR,A ;写指令代码 POP DPH POP DPL RET ;------------------------------------ ;2.写显示数据子程序(E1) PR1: PUSH DPL PUSH DPH MOV DPTR,#CRADD1 ;设置读状态字地址 PR11: MOVX A,@DPTR ;读状态宇 JB ACC.7,PR11 ;判"忙"标志为"0",否再读 MOV DPTR,#DWADD1 ;设置写显示数据地址 MOV A,DAT ;取数据 MOVX @DPTR,A ;写数据 POP DPH POP DPL RET ;------------------------------------- ;3.读显示数据子程序(E1) PR2: PUSH DPL PUSH DPH MOV DPTR,#CRADD1 ;设置读状态字地址 PR21: MOVX A,@DPTR ;读状态字 JB ACC.7,PR21 ;判"忙"标志为"0"否,否再读 MOV DPTR,#DRADD1 ;设置读显示数据地址 MOVX A,@DPTR ;读数据 MOV DAT,A ;存数据 POP DPH POP DPL RET ;------------------------------------- ;4.写指令代码子程序(E2) PR3: PUSH DPL PUSH DPH MOV DPTR,#CRADD2 ;设置读状态字地址 PR31: MOVX A,@DPTR ;读状态字 JB ACC.7,PR31 ;判"忙"陈志为"0"否,否再读 MOV DPTR,#CWADD2 ;设置写指令代码地址 MOV A,COM ;取指令代码 MOVX @DPTR,A ;写指令代码 POP DPH POP DPL RET ;------------------------------------- ; 5.写显示数据子程序(E2) PR4: PUSH DPL PUSH DPH MOV DPTR,#CRADD2 ;设置读状态字地址 PR41: MOVX A,@DPTR ;读状态字 JB ACC.7,PR41 ;判"忙"标志为"0"否,否再读 MOV DPTR, #DWADD2 ;设置写显示数据地址 MOV A,DAT ;取数据 MOVX @DPTR,A ;写数据 POP DPH POP DPL RET ;--------------------------------------- ; 6.读显示数据子程序(E2) PR5: PUSH DPL PUSH DPH MOV DPTR,#CRADD2 ;设置读状态字地址 PR51: MOVX A,@DPTR ;读状态字 JB ACC.7,PR51 ;判"忙"标志为"0",否再读 MOV DPTR,#DRADD2 ;设置写显示数据地址 MOVX A,@DPTR ;读数据 MOV DAT,A ;存数据 POP DPH POP DPL RET
; 8*16点阵字符显示程序段 WRI_EN816: MOV DPTR,#CCTAB ;确定字符字模块首地址 MOV A,CODE_SED ;取代码 MOV B,#10H ;字模块宽度为16个字节 MUL AB ;代码×16 ADD A,DPL ;字符字模块首地址 MOV DPL,A ;字模库首地址+代码×16 MOV A,B ADDC A,DPH MOV DPH,A CLR 50H PUSH COLUMN PUSH COLUMN MOV CODE_SED,#00H ;代码寄存器借用为间址寄存器 WRI_1: MOV COUNT,#8H ;计数器设置为8 MOV A,PAGE_SED ;读页地址寄存器 ANL A,#03H ;取页地址有效值 ORL A,#0B8H ;"或"页地址设置代码 MOV COM,A ;设置页地址 LCALL PR0 LCALL PR3 POP COLUMN MOV A,COLUMN ;读列地址寄存器 CLR C SUBB A,#PD1 ;列地址-模块参数 JC WRI_2 ;<0为左半屏显示区域(E1) MOV COLUMN,A ;≥0为右半屏显示区域(E2) SETB 50H ;设置区域标志位。 WRI_2: MOV COM,COLUMN ;设置列地址值 JNB 50H,WRI_3 LCALL PR3 ;区域E2 SJMP WRI_4 WRI_3: LCALL PR0 ;区域E1 WRI_4: MOV A,CODE_SED ;取间址寄存器值 MOVC A,@A+DPTR ;取汉字字模数据 MOV DAT,A ;写数据 ;MOV A,PAGE_SED JNB 50H,WRI_5 LCALL PR4 ;区域E2 SJMP WRI_6 WRI_5: LCALL PR1 ;区域E1 WRI_6: INC CODE_SED ;间址寄存器加一 INC COLUMN ;列地址寄存器加一 MOV A,COLUMN ;判列地址是否超出区域范围、 CJNE A,#PD1,WRI_7 WRI_7: JC WRI_8 ;未超出则继续 JB 50H,WRI_8 ;在区域E2 则退出 SETB 50H ;在区域E1 则修改成区域E2 MOV COM,#00H ;设置区域E2列地址为"0" LCALL PR3 WRI_8: DJNZ COUNT,WRI_4 ;当页循环 MOV A,PAGE_SED ;读页地址寄存器 JB ACC.7,WRI_9 ;判完成标志D7 位,"1"则完成退出 INC A ;否则页地址加一 SETB ACC.7 ;置完成位为"1" MOV PAGE_SED,A CLR 50H MOV CODE_SED,#8H ;间址寄存器设置为8 LJMP WRI_1 ;大循环 WRI_9: RET ;-------------------------------------- ;字符库 CCTAB: ;0 DB 0F8H,0FCH,004H,0C4H,024H,0FCH,0F8H,000H DB 007H,00FH,009H,008H,008H,00FH,007H,000H
;1 DB 000H,010H,018H,0FCH,0FCH,000H,000H,000H DB 000H,008H,008H,00FH,00FH,008H,008H,000H
;2 DB 008H,00CH,084H,0C4H,064H,03CH,018H,000H DB 00EH,00FH,009H,008H,008H,00CH,00CH,000H
;3 DB 008H,00CH,044H,044H,044H,0FCH,0B8H,000H DB 004H,00CH,008H,008H,008H,00FH,007H,000H
;4 DB 0C0H,0E0H,0B0H,098H,0FCH,0FCH,080H,000H DB 000H,000H,000H,008H,00FH,00FH,008H,000H
;5 DB 07CH,07CH,044H,044H,0C4H,0C4H,084H,000H DB 004H,00CH,008H,008H,008H,00FH,007H,000H
;6 DB 0F0H,0F8H,04CH,044H,044H,0C0H,080H,000H DB 007H,00FH,008H,008H,008H,00FH,007H,000H
;7 DB 00CH,00CH,004H,084H,0C4H,07CH,03CH,000H DB 000H,000H,00FH,00FH,000H,000H,000H,000H
;8 DB 0B8H,0FCH,044H,044H,044H,0FCH,0B8H,000H DB 007H,00FH,008H,008H,008H,00FH,007H,000H
;9 DB 038H,07CH,044H,044H,044H,0FCH,0F8H,000H DB 000H,008H,008H,008H,00CH,007H,003H,000H
;A DB 0E0H,0F0H,098H,08CH,098H,0F0H,0E0H,000H DB 00FH,00FH,000H,000H,000H,00FH,00FH,000H
;B DB 004H,0FCH,0FCH,044H,044H,0FCH,0B8H,000H DB 008H,00FH,00FH,008H,008H,00FH,007H,000H
;C DB 0F0H,0F8H,00CH,004H,004H,00CH,018H,000H DB 003H,007H,00CH,008H,008H,00CH,006H,000H
;D DB 004H,0FCH,0FCH,004H,00CH,0F8H,0F0H,000H DB 008H,00FH,00FH,008H,00CH,007H,003H,000H
;E DB 004H,0FCH,0FCH,044H,0E4H,00CH,01CH,000H DB 008H,00FH,00FH,008H,008H,00CH,00EH,000H
;F DB 004H,0FCH,0FCH,044H,0E4H,00CH,01CH,000H DB 008H,00FH,00FH,008H,000H,000H,000H,000H
;------------------------------------.
|