四. 源程序
;利用8255A设计倒计时,其中A端口连接LED显示单元的D8~D15,B口连接数码管的A~Dp, ;进行段锁存,C口高4位连接数码管的X4~X1,进行位锁存,C口的低4位作为输入端,连 ;接开关的K3~K0,其他引脚与系统总线相连
;***************根据CHECK配置信息修改下列符号值******************* IOY0 EQU 9C00H ;PCI卡中断控制寄存器地址
;***************************************************************** MY8255_A EQU IOY0+00H*4 ;8255计数器0端口地址 MY8255_B EQU IOY0+01H*4 ;8255计数器1端口地址 MY8255_C EQU IOY0+02H*4 ;8255计数器2端口地址 MY8255_MODE EQU IOY0+03H*4 ;8255控制寄存器端口地址
;***************************************************************** DATA SEGMENT
DTABLE DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH ;对应0~9 TIME DB ? ;存储倒计时的初始时间 CHU DB 10 ;存储被除数10
LA DB ? ;存储数码管从左往右亮的数值 LB DB ? ;存储数码管从右往左亮的数值 BUF DB ? ;存储输入的十位数 TISHI DB 13,10,\ TIMESUP DB 13,10,\
STRMSG DB 13,10,\ ENDMSG DB 13,10,\DATA ENDS
;***************************************************************** STACK1 SEGMENT STACK DW 256 DUP(?) STACK1 ENDS
;***************************************************************** CODE SEGMENT
ASSUME CS:CODE,DS:DATA,SS:STACK1 START: MOV AX,DATA
MOV DS,AX ;装载数据段 MOV DX,MY8255_MODE ;初始化8255 MOV AL,81H
;置8255的C口PC0~PC3输入开关状态,PC4~PC7进行数码管的位锁存B ;口的PB0~PB7进行数码管的段锁存,A口的PA0~PA7控制流水灯的点亮
OUT DX,AL
SHURU: LEA DX,TISHI ;给出输入时间提示 MOV AH,09H
INT 21H ;显示输入倒计时时间的提示 MOV AH,01H
INT 21H ;输入第1个数作为十位数
SUB AL,30H ;将AL的ASCLL减30H变为十进制的值 MOV CL,10
MUL CL ;将操作数10和AL相乘结果存入AX中 MOV BUF,AL ;把十位数存入BUF中 MOV AH,01H ;输入第2个数作为个位数 INT 21H
SUB AL,30H ;将AL的ASCII减30H变为十进制的值 ADD AL,BUF ;将两数相加作为倒计时的开始时间 MOV TIME,AL
DISPY: MOV BX,OFFSET DTABLE CBW MOV SI,3000H MOV [SI],AL MOV [SI+1],AH
C1: C2: CALL DIS
PAUSE: CALL DIS IN AL,DX
RESET1: MOV DX,MY8255_C MOV CL,TIME
;将数给TIME ;取DTABLE的偏移值 ;初值给AL
;将AX的高8位置0 ;除数10给CL
;商/十位数存入AL,余数/个位数存入AH ;定义一个缓冲区
;商/十位数存入[SI],X3中 ;余数/个位数存入[SI+1],X4中 ;保护现场 ;通过延时不断刷新数码管 ;调用显示子程序 ;通过循环调用不断刷新数码管显示 ;弹出现场 ;调用显示子程序
;C口低4位为输入 ;读入C口的最低位的状态 ;0000 0001B
最低位为1暂停倒计时 ;C口低4位为输入 ;0000 0010B 第2位置1后执行RESET2 减1倒计时 当从初始值减到0后减1则值为0FFH,计数结束
MOV AL,TIME MOV CL,CHU DIV CL PUSH AX PUSH CX
MOV CX,1FFFH MOV AX,0FFFH DEC AX
JNZ C2
LOOP C1 POP CX
POP AX MOV DX,MY8255_C TEST AL,01H JNZ PAUSE ; IN AL,DX
TEST AL,02H JNZ RESET2 ; DEC TIME ; CMP CL,0FFH ; JNZ DISPY ;倒计时未到0,继续倒计时 JMP OUTPUT1
RESET2: JMP SHURU
OUTPUT1: PUSH CX MOV CX,7 MOV LA,80H P4: MOV AL,LA
MOV DX,MY8255_A
OUT DX,AL CALL DALLY
ROR AL,1 MOV LA,AL LOOP P4
MOV CX,8
MOV LB,01H P5: MOV AL,LB
MOV DX,MY8255_A OUT DX,AL CALL DALLY
ROL AL,1 MOV LB,AL
LOOP P5
JMP prompt DALLY: PUSH CX PUSH AX
MOV CX,0FFFFH A1: MOV AX,4FFFH A2: DEC AX JNZ A2 LOOP A1 POP AX POP CX RET
DIS PROC NEAR PUSH AX PUSH DX
MOV SI,3000H MOV AL,0BFH ;1011 1111B MOV DX,MY8255_C OUT DX,AL
;跳到流水灯点亮 ;重新开始倒计时 ;点亮流水灯,流水灯0灭1亮 ;循环计数初值
;流水灯从左往右依次点亮 ;通过A口输出控制LED点亮 ;不进位的循环右移 ;流水灯从右往左依次点亮 ;不进位的循环左移 ;流水灯显示结束跳转到prompt ;流水灯点亮延时函数 ;数码管显示子程序 ;保护现场 ;找到存数的缓冲区
,选中X3数码管 ;选中PC口,进而选中数码管
MOV AL,[SI] ;取出缓冲区中存放的键值 XLAT
;查表指令,将以BX为基地址,AL为位移量的字节存储单元中的数赋给AL
MOV DX,MY8255_B ;写入数码管A~Dp OUT DX,AL
CALL DALLY1 ;调用延时函数
MOV AL,7FH ;0111 1111B,选中X4数码管 MOV DX,MY8255_C OUT DX,AL
MOV AL,[SI+1] XLAT
MOV DX,MY8255_B OUT DX,AL
CALL DALLY1 POP AX POP DX DIS ENDP
DALLY1 PROC NEAR PUSH AX PUSH CX MOV CX,0FFH C3: MOV AX,0FFH C4: DEC AX JNZ C4 LOOP C3 POP CX POP AX RET DALLY1 ENDP
prompt: LEA DX,TIMESUP CALL PUTS
LEA DX,STRMSG CALL PUTS P3: MOV AH,1
INT 21H CMP AL,72H JZ P1
CMP AL,65H JZ P2
JMP P3
P1: JMP RESET2 ;选中PC口,进而选中数码管 ;取出缓冲区中存放的键值 ;写入数码管A~Dp ;调用延时函数 ;数码管显示延时函数 ;将TIMESUP字符串输出 ;将STR字符串输出 ;键盘输入单个字符,AL=输入字符的ASCII码 ;测试按下的键为‘r’重新开始 ;测试按下的键为‘e’退出 ;不处理其他按键的输入 ;重新开始
P2: LEA DX,ENDMSG CALL PUTS
MOV AH,4CH INT 21H PUTS: MOV AH,9
INT 21H RET
CODE ENDS END START
;退出程序
;进行字符串显示 ;程序结束
五. 总结
通过本次微机接口课程设计,让我对微机原理与接口技术和汇编语言的了解更加深刻。我和我的组员王乐在TD-PIT+实验系统和PC机平台上利用并行接口8255A、键盘及数码管显示单元、开关及LED显示单元、键盘按键和电脑显示屏设计成一个倒计时器,最终很完美地实现了所有基本功能和扩展功能,感觉很有自豪感。
在这次课设中,我学到了很多,包括书本上的和书本外平时易忽视的东西。一方面锻炼了我的动手能力,一方面提升了我的分析问题和解决问题的能力,还有就是团队合作精神。在这过程中,我们遇到了很多问题,最突出的就是数码管显示问题,我们一起讨论研究并询问老师,最终都很完美地解决了所有问题,设计出了一个多功能的倒计时器。
感谢XXX老师的细心指导,感谢我的组员XX,最后感谢学校给我们提供这么好的学习平台。