中南大学微机课程设计
8086源程序如下:
- INCLUDE ZUOZHE.INC
- INCLUDE HUANYING.inc
- INCLUDE ZAIJIAN.inc
- INCLUDE DAIJI.inc
- .386P
- IOY0 EQU 3000H ;片选 IOY0 对应的端口始地址
- IOY1 EQU 3040H
- IOY2 EQU 3080H
- IOY3 EQU 30C0H
- MY8251_DATA EQU IOY2+00H*4 ;8251 数据寄存器
- MY8251_MODE EQU IOY2+01H*4 ;8251 方式控制寄存器
- MY8254_COUNT2 EQU IOY3+02H*4 ;8254 计数器 2 端口地址
- MY8254_MODE EQU IOY3+03H*4 ;8254 控制寄存器端口地址
- MY8255_A EQU IOY0+00H*4 ;8255 的 A 口地址
- MY8255_B EQU IOY0+01H*4 ;8255 的 B 口地址
- MY8255_C EQU IOY0+02H*4 ;8255 的 C 口地址
- MY8255_MODE EQU IOY0+03H*4 ;8255 的控制寄存器地址
- STACK1 SEGMENT STACK
- DW 256 DUP(?)
- STACK1 ENDS
- DATA SEGMENT USE16
- ADDR DW ?
- DTABLE DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH,77H,7CH,39H,5EH,79H,71H
- STR2 DB ' 1
- STR3 DB ' 2
- STR4 DB ' 3
- STR5 DB ' BYE-BYE
- DATA ENDS
- CODE SEGMENT USE16
- ASSUME CS:CODE,DS:DATA
- START: MOV AX,DATA
- MOV DS,AX
- A2: MOV ADDR,OFFSET ZUOZHE
- MOV SI,ADDR
- A1: MOV CX,20H
- LOOP2: CALL DISPHZ
- SUB SI,32
- LOOP LOOP2
- CALL CCSCAN
- JNZ BEGIN
- ADD SI,2
- MOV AX,SI
- SUB AX,ADDR
- CMP AX,96 ;比较文字是否显示完毕
- JNB A2
- JMP A1
- BEGIN: MOV SI,3000H ;建立缓冲区,存放要显示的键值
- MOV AL,00H ;先初始化键值为0
- MOV [SI],AL
- MOV [SI+1],AL
- MOV [SI+2],AL
- MOV [SI+3],AL
- MOV [SI+4],AL
- MOV [SI+5],AL
- MOV DI,3005H
- MOV DX,MY8255_MODE ;初始化 8255 工作方式
- MOV AL,81H ;方式 0,A 口、B 口输出,C 口低 4 位输入
- OUT DX,AL
- CALL DIS ;显示刷新
- CALL CLEAR ;清屏
- CALL CCSCAN ;扫描按键
- JNZ GETKEY1 ;有键按下则跳置 GETKEY1
- JMP BEGIN ;无按键则跳回继续循环,有则退出
- QUIT: MOV AX,4C00H ;返回到 DOS
- INT 21H
- GETKEY1:MOV CH,0FEH
- MOV CL,00H ;设置当前检测的是第几列
- COLUM: MOV AL,CH ;选取一列,将 X1~X4 中一个置 0
- MOV DX,MY8255_A
- OUT DX,AL
- MOV DX,MY8255_C ;读 Y1~Y4,用于判断是哪一行按键闭合
- IN AL,DX
- L1: TEST AL,01H ;是否为第 1 行
- JNZ L2 ;不是则继续判断
- MOV AL,01H
- CALL PUTBUF
- JMP KEY1
- L2: TEST AL,02H ;是否为第 2 行
- JNZ L3 ;不是则继续判断
- MOV AL,02H
- CALL PUTBUF
- JMP KEY2
- L3: TEST AL,04H ;是否为第 3 行
- JNZ L4 ;不是则继续判断
- MOV AL,03H
- CALL PUTBUF
- JMP KEY3
- L4: TEST AL,08H ;是否为第 4 行
- JNZ COLUM ;不是则继续判断
- MOV AL,04H
- CALL PUTBUF
- JMP KEY4
- KEY1: CALL FINSH
- PUSH AX
- CALL DIS ;显示刷新
- POP AX
- PUSH BX
- MOV BX,OFFSET STR2
- CALL STRING
- POP BX
- A21: MOV ADDR,OFFSET HUANYING
- MOV SI,ADDR
- A11: MOV CX,20H
- LOOP21: CALL DISPHZ
- SUB SI,32
- LOOP LOOP21
- CALL CCSCAN
- JNZ BEGIN
- ADD SI,2
- MOV AX,SI
- SUB AX,ADDR
- CMP AX,96 ;比较文字是否显示完毕
- JNB A21
- JMP A11
- KEY2: CALL FINSH
- PUSH AX
- CALL DIS ;显示刷新
- POP AX
- MOV BX,OFFSET STR3
- CALL STRING
- A22: MOV ADDR,OFFSET DAIJI
- MOV SI,ADDR
- A12: MOV CX,20H
- LOOP22: CALL DISPHZ
- SUB SI,32
- LOOP LOOP22
- CALL CCSCAN
- JNZ BEGIN
- ADD SI,2
- MOV AX,SI
- SUB AX,ADDR
- CMP AX,256 ;比较文字是否显示完毕
- JNB A22
- JMP A12
- KEY3: CALL FINSH
- PUSH AX
- CALL DIS ;显示刷新
- POP AX
- MOV BX,OFFSET STR4
- CALL STRING
- A23: MOV ADDR,OFFSET ZAIJIAN
- MOV SI,ADDR
- A13: MOV CX,20H
- LOOP23: CALL DISPHZ
- SUB SI,32
- LOOP LOOP23
- CALL CCSCAN
- JNZ BEGIN
- ADD SI,2
- MOV AX,SI
- SUB AX,ADDR
- CMP AX,96 ;比较文字是否显示完毕
- JNB A23
- JMP A13
- KEY4: CALL FINSH
- PUSH AX
- MOV BX,OFFSET STR5
- CALL STRING
- CALL DIS ;显示刷新
- POP AX
- CALL CLEAR
- MOV AX,4C00H ;结束程序退出
- INT 21H
- CCSCAN PROC NEAR ;扫描是否有按键闭合子程序
- MOV AL,00H
- MOV DX,MY8255_A ;将 4 列全选通,X1~X4 置 0
- OUT DX,AL
- MOV DX,MY8255_C
- IN AL,DX ;读 Y1~Y4
- NOT AL
- AND AL,0FH ;取出 Y1~Y4 的反值
- RET
- CCSCAN ENDP
- DISPHZ PROC NEAR ;显示 1 屏汉字子程序
- PUSH CX
- MOV CX,16
- MOV BX,0FFFEH
- LOOP1: MOV AL,BYTE PTR[SI]
- MOV AH,BYTE PTR[SI+1]
- ROL EAX,16
- MOV AX,BX
- ADD SI,2
- ROL BX,1
- NOT EAX
- MOV DX,IOY1
- OUT DX,EAX
- CALL DALLY
- LOOP LOOP1
- POP CX
- RET
- DISPHZ ENDP
- DALLY PROC NEAR ;软件延时子程序
- PUSH CX
- PUSH AX
- MOV CX,09H
- D1: MOV AX,0F000H
- D2: DEC AX
- JNZ D2
- LOOP D1
- POP AX
- POP CX
- RET
- DALLY ENDP
- FINSH PROC NEAR
- MOV EAX,0 ;灭灯
- MOV DX,IOY1
- OUT DX,EAX
- RET
- FINSH ENDP
- DIS PROC NEAR ;显示键值子程序
- PUSH AX ;以缓冲区存放的键值为键值表偏移找到键值并显示
- MOV SI,3000H
- MOV DL,0DFH
- MOV AL,DL
- AGAIN: PUSH DX
- MOV DX,MY8255_A
- OUT DX,AL ;设置X1~X4,选通一个数码管
- MOV AL,[SI] ;取出缓冲区中存放键值
- MOV BX,OFFSET DTABLE
- AND AX,00FFH
- ADD BX,AX
- MOV AL,[BX] ;将键值作为偏移和键值基地址相加得到相应的键值
- MOV DX,MY8255_B
- OUT DX,AL ;写入数码管A~Dp
- CALL DALLY
- INC SI ;取下一个键值
- POP DX
- MOV AL,DL
- TEST AL,01H ;判断是否显示完?
- JZ OUT1 ;显示完,返回
- ROR AL,1
- MOV DL,AL
- JMP AGAIN ;未显示完,跳回继续
- OUT1: POP AX
- RET
- DIS ENDP
- CLEAR PROC NEAR ;清除数码管显示子程序
- MOV DX,MY8255_B ;段位置0即可清除数码管显示
- MOV AL,00H
- OUT DX,AL
- RET
- CLEAR ENDP
- PUTBUF PROC NEAR ;保存键值子程序
- MOV SI,DI
- MOV [SI],AL
- DEC DI
- CMP DI,2FFFH
- JNZ GOBACK
- MOV DI,3005H
- GOBACK: RET
- PUTBUF ENDP
- STRING PROC NEAR
- MOV AL, 0B6H ;初始化 8254,得到收发时钟
- MOV DX, MY8254_MODE
- OUT DX, AL
- MOV AL, 0CH
- MOV DX, MY8254_COUNT2
- OUT DX, AL
- MOV AL, 00H
- OUT DX, AL
- CALL INIT ;初始化 8251
- CALL DALLY1
- MOV AL,7EH
- MOV DX, MY8251_MODE
- OUT DX, AL ;8251 方式字
- CALL DALLY1
- MOV AL, 34H
- OUT DX, AL ;8251 控制字
- CALL DALLY1
- MOV CX, 0016H ;10 个数
- A111: MOV AL, 37H
- MOV DX, MY8251_MODE
- OUT DX, AL
- MOV AL, [BX]
- MOV DX, MY8251_DATA
- OUT DX, AL ;发送数据
- MOV DX, MY8251_MODE
- A222: IN AL, DX ;判断发送缓冲是否为空
- AND AL, 01H
- JZ A222
- CALL DALLY
- A333: IN AL, DX ;判断是否接收到数据
- AND AL, 02H
- JZ A333
- MOV DX, MY8251_DATA
- IN AL, DX ;读取接收到的数据并显示
- MOV DL,AL
- MOV AH,02H
- INT 21H
- INC BX
- LOOP A111
- RET
- STRING ENDP
- INIT PROC NEAR
- MOV AL, 00H ;复位 8251 子程序
- MOV DX, MY8251_MODE
- OUT DX, AL
- …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
所有资料51hei提供下载:
微机课程设计.zip
(5.55 KB, 下载次数: 33)
|