5.本次课设汇编代码
5.1基本地址\字码写入
先记录各个硬件的地址编码,写入需要输出的字符串的二进制码,新建空白缓存区域等。
io8255c equ 28ah ;8253(LCD特定口PC0~PC3)
io8255k equ 28bh
io8255a equ 288h ;继电器(LCD)
io8255b equ 289h ;数码管
io8253_0 equ 280h
io8253_k equ 283h
io8253_1 equ 281h
DATA SEGMENT
MES1 DB 'THIS IS LHI958...',0DH,0AH,24H
HZ_TAC DW 0CEDEH,0D5DAH,0B5B2H,0CEEFH ;"无遮挡物"
DW 0A3AEH,0A3AEH,0A3AEH,0A3AEH ;" "(四个空格)
DW 0CEDEH,0D5DAH,0B5B2H,0CEEFH
DW 0A3AEH,0A3AEH,0A3AEH,0A3AEH
HZ_TAB DW 0BEAFH,0B8E6H, 0BEAFH,0B8E6H ; "警告警告"
DW 0A3A1H,0A3A1H,0A3A1H,0A3A1H ; "!!!!"
DW 0BADAH,0D2B9H, 0D3D0H,0C8CBH ; "黑夜有人"
DW 0A3A1H,0A3A1H,0A3A1H,0A3A1H ; "!!!!"
HZ_TAD DW 0D3D0H,0D5DAH,0B5B2H,0CEEFH; "有遮挡物"
DW 0A3AEH,0A3AEH,0A3AEH,0A3AEH
DW 0D3D0H,0D5DAH,0B5B2H,0CEEFH
DW 0A3AEH,0A3AEH,0A3AEH,0A3AEH;
HZ_ADR DB ? ;地址缓存
5.2代码段
本次课程设计完整代码段代码详见本文章绑定资源。
下面可介绍本实验装置关于数码管与键盘相互配合的代码调用的汇编实现(与本次课程设计无关,但可以提供撰写数码管代码和案件代码的思路,便于读者创新)。
该实验的接线如下:可以实现按键按下数字几,数码管显示几。
(1)PC7~PC0 /8255 接 行 3~列 0 /4X4 键盘。
(2)PA7~PA0 /8255 接 dp~a /LED 数码管。
(3)CS/8255 接 Y1 /IO 地址。
(4)+5V 接 S0 /LED 数码管。
(5)GND 接 S3~S1 /LED 数码管。
a8255 equ 288H ;8255 A 口地址
c8255 equ 28aH ;8255 C 口地址
k8255 equ 28bH ;8255 控制口地址
data segment
table1 dw 0770h,0B70h,0D70h,0E70h,07B0h,0BB0h,0DB0h,0EB0h
dw 07D0h,0BD0h,0DD0h,0ED0h,07E0h,0BE0h,0DE0h,0EE0h
;键盘扫描码表,AH 低四位对应列,AL 高四位对应行,例如 A 在第二行第二
列对应的码值为 0000,1101,1101,0000,即 0DD0H
LED DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH,77H,7CH
DB 39h,5EH,79h,71h,0ffh ;LED 七段数码管 0~F 的段码
char db '0123456789ABCDEF' ;字符表
mes db 0ah,0dh,'PLAY ANY KEY IN THE SMALL KEYBOARD! ',0ah,0dh
db 'IT WILL BE ON THE SCREEN! END WITH E ',0ah,0dh,'$'
key_in db 0h
data ends
stacks segment stack ;堆栈段
db 100 dup (?)
stacks ends
code segment
assume cs:code,ds:data,ss:stacks,es:data
start:
cli
mov ax,data
mov ds,ax
mov es,ax
mov ax,stacks
mov ss,ax
mov dx,offset mes ;打印 mes 存的字符串
mov ah,09
int 21h
MOV DX,k8255 ;初始化 8255 控制字
mov al,81h ;设置 8255A 口输出,PC0~3 输入
out dx,al
main_key:
call key ;调用子程序,判断是哪一个按键被按下
call disply ;调显示子程序,显示得到的字符
cmp byte ptr key_in,'E'
jnz main_key
mov ax,4c00h ;
int 21h ;退出
;
key proc near
key_loop:
mov ah,1 ;用来查询键盘缓冲区
int 16h ;若有按键操作则 ZF=0
jnz exit ;pc 键盘无键按下则退出
;对 PC0~3 置位,PC4~7 全部复位,进行初始化,防止对后续检测造成干扰
mov dx,c8255
mov al,0fh
out dx,al
in al,dx ;获取按键输出给 8255 的信号,并存于 AL
and al,0fh
cmp al,0fh ;键盘行线输出检测,若某行按下,则对应位置 0
jz key_loop ;如果没有按键按下,或传输信息有误时,则重新检测
call delay
mov ah,al ;将行线的输出传给 AH 低四位保存
MOV DX,k8255
mov al,88h ;初始化控制字,PC4~7 口输入
out dx,al
mov dx,c8255
mov al,ah
or al,0f0h ;AL 高四位全部置一,防止对列线输出检测造成干扰
out dx,al
in al,dx ;读列扫描值
and al,0f0h
cmp al,0f0h ;键盘列线输出检测,若某列按下,则 AL4~7 对应位
置 0,最终 AX 中 AH 低四位存放行列码,AL 高四位存放列码
jz key_loop ;如果没有按键按下,或传输信息有误时,则重新检测
mov si,offset tablel ;键盘扫描码表首址
mov di,offset char ;字符表首址
mov cx,16 ;循环次数=待查字符数(0~F)
key_tonext:
cmp ax,[si] ;AX 存放着检测到的按键对应的编码,在 SI 所指向
的地址空间进行遍历对比,查找在 tab1el 向量中与之相同的编码对应的序号 CX
jz key_findkey ;找到字符则跳转
dec cx
;如果遍历所有代码后未能找到,则返回 key_loop 重新检测
jz key_loop
add si,2
inc di ;对查询到的字符地址进行计数,便于确认是哪个字符。
jmp key_tonext ;若未遍历结束且没找到则跳回 key_tonext 继续查找
key_findkey:
mov dl,[di]
mov ah,02
int 21h ;终端显示查找到的键盘码
mov byte ptr key_in,dl ;要显示的段码地址存放在 key_in
;不支持连续按按键
key_waitup:
MOV DX,k8255
mov al,81h
out dx,al
mov dx,c8255
mov al,0fh
out dx,al
in al,dx ;读行扫描值
and al,0fh
cmp al,0fh
jnz key_waitup ;按键未松手继续等待
call delay
ret
exit: mov byte ptr key_in,'E'
ret
key endp
delay proc near
push ax ;delay 50ms--100ms
mov ah,0
int 1ah
mov bx,dx
delay1:
mov ah,0
int 1ah
cmp bx,dx
jz delay1
mov bx,dx
delay2:
mov ah,0
int 1ah
cmp bx,dx
jz delay2
pop ax
ret
delay endp
DISPLY PROC NEAR
PUSH ax
MOV BX,OFFSET LED ;将段码预先存入 BX,后续 XLAT 调用
MOV AL,byte ptr key_in
SUB al,30h ;将数字 0~9 的 ASCII 码转换为真实数字
CMP al,09h
JNG DIS2
SUB al,07h ;将字符 A~F 对应的 ASCII 码转换为真实字符
DIS2: XLAT ;利用制表符使得 AX 与 BX 的地址相加,使得 AL 为要
显示的字符的段码,以便于后续输出
MOV DX,a8255
OUT DX,AL ;输出显示数据,段码
POP AX
RET
DISPLY ENDP
code ends
end start
6.实验效果
无人触发时,实验现象图 6- 1,LCD 显示“无人遮挡”,数码管显示“FF”。
当对光敏电阻进行遮挡时,模拟晚上,则实验现象如图 6- 2,LCD 显示“警 告警告,黑夜有人”,数码管显示 00。
当没遮挡光敏电阻,模拟白天,则实验现象如图 6- 3,LCD 显示“有人遮挡”,数码管显示“00”。
Design by qxl、sru、gxy、ap.