📄 8255_kb.asm
字号:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; 8255小键盘实验,缺省连线
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
.386
.model flat, stdcall
option casemap:none
;**************头文件和导入库文件****************************
include windows.inc
include user32.inc
include kernel32.inc
includelib user32.lib
includelib kernel32.lib
;**************equ******************************
IDD_DIALOG1 equ 102
IDC_CHAR equ 1001
IDC_STOP equ 3
;**************data?****************************
.data
wIO_Base2 dw 0A400H ; IO address 2
w8255_OFFSET dw 0
Failure db '创建线程失败!',0
Col_Num db -1,0,1,-1,2,-1,-1,-1,3,7 dup(-1)
Char_Table db '048C159D26AE37BF',0
ShowChar db 0,0
.data?
w8255_PA dw ?
w8255_PB dw ?
w8255_PC dw ?
w8255_CTRL dw ?
hDlg dd ?
ThreadID dd ?
hThread dd ?
nRet dd ?
;**************代码段****************************
.code
;=============================================================
;行扫描法识别按键,扫描一遍(0~3行)
;当有键按下时,在al中返回按下键对应的字符ASCII码
;当无键按下时,在al中返回0
;=============================================================
LScan_KeyBoard proc
Local Line_Init:BYTE
mov Line_Init,00000001B
;----某一行送1,其余行送0-----
mov cl,0
.while (cl<4)
mov dx,w8255_PC
mov al,Line_Init
out dx,al
nop
in al,dx
and al,0F0H
.if (al==0);---无键按下,则扫描下一行---
rol Line_Init,1
inc cl
.else ;---有键按下---
shr al,4
lea ebx,Col_Num ;---查表求列号(0~3),在al中---
xlat
mov ah,cl ;====ah中为行号,al中为列号====
;====计算位置号:行号*4+列号====
shl ah,2
add al,ah
;====查表得出位置号所对应的字符====
lea ebx,Char_Table
xlat
.break ;===当有键按下退出循环时,在al中返回按下键对应的字符ASCII码===
.endif
.endw
.if (cl==4) ;===当无键按下退出循环时,在al中返回0===
mov al,0
.endif
ret
LScan_KeyBoard endp
Scan_Thread proc
@@:invoke LScan_KeyBoard
.if al!=0 ;表明有键按下,al中为按下键的ASCII码
mov ShowChar,al
invoke SetDlgItemText,hDlg,IDC_CHAR,addr ShowChar;显示字符
.endif
jmp @B ;循环扫描
ret
Scan_Thread endp
DlgProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
.if uMsg == WM_INITDIALOG
push hWnd
pop hDlg
;-------计算8255端口地址-------
mov ax,wIO_Base2
add ax,w8255_OFFSET
mov w8255_PA,ax
inc ax
mov w8255_PB,ax
inc ax
mov w8255_PC,ax
inc ax
mov w8255_CTRL,ax
;------初始化8255,行扫描法:PC口高位(列值)输入,低位(行值)输出----
mov dx,w8255_CTRL
mov al,10001000B
out dx,al
;-------使“停止扫描”按钮无效--------
invoke GetDlgItem,hWnd,IDC_STOP
invoke EnableWindow,eax,FALSE
.elseif uMsg == WM_CLOSE
invoke TerminateThread, hThread, 0
invoke EndDialog, hWnd,NULL
.elseif uMsg == WM_COMMAND
mov eax, wParam
.if ax == IDOK
;------------------------------------------------
; 当按下该按钮后,创建一个线程,用于扫描小键盘
;------------------------------------------------
invoke CreateThread, NULL, 0, addr Scan_Thread, NULL, NULL, addr ThreadID
.if eax
mov hThread, eax
;-------使“开始扫描”按钮无效--------
invoke GetDlgItem,hWnd,IDOK
invoke EnableWindow,eax,FALSE
;-------使“停止扫描”按钮有效--------
invoke GetDlgItem,hWnd,IDC_STOP
invoke EnableWindow,eax,TRUE
.else
invoke MessageBox, NULL, addr Failure, addr Failure, MB_OK
.endif
.elseif ax == IDC_STOP
;------------------------------
;停止扫描,中止扫描线程
;-------------------------------
invoke TerminateThread, hThread, 0
;-------使“停止扫描”按钮无效--------
invoke GetDlgItem,hWnd,IDC_STOP
invoke EnableWindow,eax,FALSE
;-------使“开始扫描”按钮有效--------
invoke GetDlgItem,hWnd,IDOK
invoke EnableWindow,eax,TRUE
.elseif ax == IDCANCEL
invoke TerminateThread, hThread, 0
invoke EndDialog, hWnd, NULL
.endif
.else
mov eax,FALSE
ret
.endif
mov eax,TRUE
ret
DlgProc endp
;====================================================================
start:
invoke GetModuleHandle, NULL
invoke DialogBoxParam, eax, IDD_DIALOG1, NULL, DlgProc, NULL
invoke ExitProcess, NULL
end start
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -