|
原创的西电微机原理实验 包括汇编源文件和对应的Proteus仿真电路 可以直接在电脑上运行仿真 完成的功能与要求在实验板上完成的功能一样
- ;各种地址
- nCS5 EQU 0DE28H
- PA8255 EQU nCS5+0
- PB8255 EQU nCS5+2
- PC8255 EQU nCS5+4
- CTL8255 EQU nCS5+6
- DISPBUFF EQU 3000H
- ;按键抖动时间
- KeyShock EQU 06FFFH
-
- DATAS SEGMENT
- ;此处输入数据段代码
- ;数码管段码 0 1 2 3 4 5 6 7 8 9 A B C D E F
- SegCode DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH,77H,7CH,39H,5EH,79H,71H
- ;矩阵键盘按键码 0 1 2 3 4 5 6 7 8 9 A B C D E F
- KeyCode DB 11H,21H,41H,81H,12H,22H,42H,82H,14H,24H,44H,84H,18H,28H,48H,88H
- DATAS ENDS
- STACKS SEGMENT
- ;此处输入堆栈段代码
- STACKS ENDS
- CODES SEGMENT
- ASSUME CS:CODES,DS:DATAS,SS:STACKS
- START:
- MOV AX,DATAS
- MOV DS,AX
- ;将8086控制总线拉到确定电平
- MOV DX,00H
- OUT DX,AL
- IN AL,DX
- ;此处输入代码段代码
-
- ;初始化数码管显示缓冲区
- InitBuff:
- MOV SI,DISPBUFF
- MOV CX,4
- Loop1:
- MOV [SI],CL
- INC SI
- LOOP Loop1
-
-
-
- ;主函数...
- MOV DI,03H
-
- Loop3:
- CALL Disp
- CALL MatrixKeyboard
- JMP Loop3
-
- ;矩阵键盘扫描子函数
- MatrixKeyboard PROC
- Begin:
- ;初始化8255控制字
- MOV DX,nCS5 + 6
- MOV AL,10001000B ;PC高4位作键盘扫描列信号,PC低4位作键盘扫描行信号
- OUT DX,AL
-
- Scan:
- ;PC口
- MOV DX,nCS5 + 4 ;PC行扫描给出全低电平
- MOV AL,00H
- OUT DX,AL
- WaitKey:
- IN AL,DX ;读出PC列扫描电平
- AND AL,0F0H ;去除低4位,保留高4位
- CMP AL,0F0H ;将得到的列电平和F0H比较,如果相等说明列线全高,没有按键按下
- JZ ExtiKeyboard ;如果没有按键按下,直接返回
-
- MOV CX,KeyShock ;如果有按键按下,先延时一会,去抖动
- LOOP $
- ;开始正反向扫描
- IN AL,DX ;读取列值
- AND AL,0F0H
- CMP AL,0F0H
- JZ ExtiKeyboard ;如果再次读到的结果是高电平,表明前次按下是抖动,不予理会
- MOV CL,AL ;如果确实有按键按下则记录列地址
-
- MOV DX,nCS5 + 6 ;重新设置控制字
- MOV AL,10000001B ;PC行列翻转,高4位做键盘扫描行信号,低4为作键盘扫描行信号
- OUT DX,AL
-
- MOV DX,nCS5 + 4 ;PC行扫描给出全低电平
- MOV AL,00H
- OUT DX,AL
-
- IN AL,DX
- AND AL,0FH ;取低4位
- OR AL,CL ;将正向和反向的合成按键码
-
- MOV BX,OFFSET KeyCode
- MOV SI,00H
- NOT AL ;AL取反,完全只是为了计算按键码方便
-
- ScanKey:
- CMP AL,[BX][SI] ;将读到的键码和键码表比较
- JE FindKey ;如果相等(找到),调到找到处理部分
- INC SI ;如果不相等,再跟下一个比较
- CMP SI,10H
- JZ Begin ;找到第16个还没找到表示按键非法,重新从头开始扫描
- JMP ScanKey ;与键码表中下一个键码比较
- FindKey:
- CALL PutBuff
- ;MOV BX,DISPBUFF
- ;MOV [BX],SI
- ExtiKeyboard:
- RET
- MatrixKeyboard ENDP
- PutBuff PROC
-
- MOV BX,DISPBUFF
- ADD BX,DI
-
- MOV AX,SI
- MOV [BX],AL
- DEC DI
- JNC Finish
- MOV DI,03H
- Finish:
- RET
- PutBUff ENDP
-
- ;数码管显示子函数
- Disp PROC
- MOV SI,DISPBUFF
- MOV CL,0FEH
-
- Loop2:
- MOV AL,CL
- MOV DX,PB8255 ;位选
- OUT DX,AL
-
- MOV BX,OFFSET SegCode
- MOV AX,0
- MOV AL,[SI]
- ADD BX,AX
- MOV AL,[BX]
- MOV DX,PA8255
- OUT DX,AL
-
- CALL DelayMs
- CALL ClearDig
-
- CMP CL,0F7H ;判断有没有一遍扫完
- JZ ExitDisp
-
- INC SI
- ROL CL,1
-
- JMP Loop2
-
- ExitDisp:
- RET
- DISP ENDP
- ;清除数码管显示子函数
- ClearDig PROC
- MOV DX,PA8255
- MOV AL,00H
- OUT DX,AL
- RET
- ClearDig ENDP
- ;延时子函数
- DelayMs PROC
- PUSH AX ;保护原先的寄存器内容
- PUSH BX
-
- MOV AX,00FFH
- L2: MOV BX,000FH
- L3: DEC BX
- JNZ L3
- DEC AX
- JNZ L2
-
- POP BX ;恢复原先的寄存器内容,注意这里的弹栈顺序
- POP AX
-
- RET
- DelayMs ENDP
-
- ;收尾工作
- JMP $
- MOV AH,4CH
- INT 21H
- CODES ENDS
- END START
复制代码
|
|