热身
测接口实验
测试实验台的 8255 接口是否完好,可以这么测:按下一个键, LED 显示对应开关的打开与否。我们组运气比较倒霉,第一天时碰到有坏的接口。
需要注意的地方:把端口号(我们的实验台 IOY0 是 0600H,状态控制字端口是 0606H,控制字 82H 表示 B口输入 其他口输出),状态控制字都检验一遍,查看 8255 每个端口是否能正常输入输出。
;(1)按下任意一个键,LED显示对应开关的打开与否 IOY0 EQU 0600H AA EQU IOY0+0*2 BB EQU IOY0+1*2 CC EQU IOY0+2*2 MODE EQU IOY0+3*2 STACK1 SEGMENT STACK DW 256 DUP(?) STACK1 ENDS CODE SEGMENT ASSUME CS:CODE,SS:STACK1 START: MOV DX,MODE MOV AL,82H OUT DX,AL NEXT: MOV DX,BB IN AL,DX MOV DX,AA OUT DX,AL MOV AH,1 JMP NEXT MOV AH,4CH INT 21H CODE ENDS END START
流水灯实验要求
能够在自行设计的接口开发板上,利用不同开关控制 LED 灯的变化。例如:K1 从左往右,K2 从右往左,K3 从中间向两边,K4 从两边向中间依次亮灭变化
解法
这段代码当时做的时候没存储,不过代码的逻辑很简单:设置好实验台上的端口输出与状态字相关操作后,利用一个十六位的寄存器负责将数据输出到两个八排 LED 灯,每次循环执行 ROR 或者 ROL(根据需求而定)。
当时的实验台:
下面这段代码只是一个 Demo,可以以此基础上改:
;(2)流水灯实验 IOY0 EQU 0600H AA EQU IOY0+0*2 BB EQU IOY0+1*2 CC EQU IOY0+2*2 MODE EQU IOY0+3*2 STACK1 SEGMENT STACK DW 256 DUP(?) STACK1 ENDS CODE SEGMENT ASSUME CS:CODE,SS:STACK1 START: MOV DX,MODE 这几行是设置控制字 MOV AL,80H ;80H 输出, 82H输入 OUT DX,AL MOV BL,80H MOV BH,01H NEXT: MOV DX,AA 输出步骤:1、设置值 2、设置地址 3、向端口输出 MOV AL,BL OUT DX,AL MOV DX,BB MOV AL,BH OUT DX,AL CALL DELAY ROR BL,1 ROL BH,1 JMP NEXT MOV AH,4CH INT 21H DELAY PROC NEAR MOV CX,20H D1: MOV AX,0FFFFH D2: DEC AX JNZ D2 LOOP D1 RET DELAY ENDP CODE ENDS END START
汽车控制
我们的汽车控制逻辑是这样:利用两个数码管显示汽车速度,一个数码管显示档位,4个开关控制速度的增加与减少,K1 为 1 挡(10 km/h),K2 为 2 挡(20 km/h),K3 为 4挡(40km/h),K4 为 6挡(60km/h),加速时只能依次加,而不能直接增加到 6挡,减速时可以直接从 60 减速到 0。
实现难点在于数码管的动态显示:由于四位一体数码管同用一个串口进行输入,这样的话我们就不能分别送不同的值给四个数码管,所以需要通过 8255 的 C 口输出数码管地址口而不是将数码管地址口全部接 GND,使其中三个接地,一个接高电平(相当于这个口输入为 1),使得某一个数码管亮而其他几个是熄灭的。然后再传值,传入的值是将速度除以 10 之后的十位数字或者是各位数字,采用 div 指令实现。然后我们通过改变延时时长与 call 子程序的次数,改变每个灯亮的间隔,让肉眼感觉多个数码管同时在改变数字。
代码部分
IOY0 EQU 0600H ;片选IOY0对应的端口始地址 MY8255_A EQU IOY0+00H*2 ;8255的A口地址 MY8255_B EQU IOY0+01H*2 ;8255的B口地址 MY8255_C EQU IOY0+02H*2 ;8255的C口地址 MY8255_MODE EQU IOY0+03H*2 ;8255的控制寄存器地址 SSTACK SEGMENT STACK DW 32 DUP(?) SSTACK ENDS DATA SEGMENT NUMS DB 3FH,06H,5BH,4FH,66h,6dh,7dh,07h,7fh,6fh,79H ; ;SELECT_OUTSMG1 DB 0H, 0FEH, 0FDH, 0FBH, 0F7H DATA ENDS CODE SEGMENT ASSUME CS:CODE,SS:SSTACK START: MOV AX,DATA MOV DS,AX MOV AX,SSTACK MOV SS,AX MOV DX, MY8255_MODE MOV AL, 82H ;1000 0001 表示A口C口高四位低四位输出,B口为输入 OUT DX, AL ;控制字送控制寄存器 MOV BX, 0 ;清零 CTRL: MOV DX , MY8255_B IN AL, DX ;C口值送AL,进行输入 MOV AH,0 ;AX的高8位清零 TEST AL,1H ;AL是否等于1,进行and操作,影响标志位 JNZ T1 ;若AL为XXXX XXX1,跳T1 MOV CX ,00 ;CX送0 JMP A1 T1: TEST AL, 2H JNZ T2 ;若AL为XXXX XX1X,跳T2 MOV CX,10 ;CX送10 MOV DX , MY8255_B mov AL,00010000B ; out DX, AL ;将AL的值给C口 JMP A1 T2: TEST AL, 4H JNZ T3 ;若AL为XXXX X1XX,跳T3 MOV CX, 20 ;CX送20 MOV DX , MY8255_B mov AL, 00100000B out DX, AL JMP A1 T3: TEST AL,8H JNZ T4 ;若AL为XXXX 1XXX,跳T4 MOV CX,40 MOV DX , MY8255_B mov AL,01000000B out DX, AL JMP A1 T4: MOV CX,60 ;CX送60 MOV DX , MY8255_B mov AL,10000000B out DX, AL JMP A1 A1: CMP BX,CX JNZ AMD ;ZF=0,跳AMD CMP BX,0 JE CWT ;ZF=1,跳CWT AMD: CMP CX,BX JB ASD ;CX小于BX,跳ASD CALL PRINT1 ;执行子程序,会返回 JMP CTRL ASD: CALL PRINT2 JMP CTRL CWT: CALL PRI JMP CTRL PRINT1 PROC ;因为每次只能亮1个的原因,所以要call多次实现肉眼错觉 CALL PRI CALL PRI CALL PRI CALL PRI CALL PRI CALL PRI CALL PRI CALL PRI CALL PRI CALL PRI CALL PRI ;CALL PRI ;CALL PRI ;CALL PRI INC BX CMP BX,CX JB PRINT1 MOV BX,CX RET PRINT1 ENDP PRINT2 PROC CALL PRI CALL PRI CALL PRI CALL PRI CALL PRI CALL PRI CALL PRI CALL PRI CALL PRI CALL PRI CALL PRI ;CALL PRI ;CALL PRI ;CALL PRI DEC BX CMP CX,BX JB PRINT2 MOV BX,CX RET PRINT2 ENDP PRI PROC PUSH CX PUSH DX PUSH AX PUSH BX ;速度高位 MOV AX,BX MOV CL,10 DIV CL ; AH 余数 AL 商 36 / 10 = 3 ..... 6 MOV CX,0 MOV CX,14 ;0000 1110b,就是设置第一个数码管亮 MOV BL,AL ; 3 CALL HUA CALL YANSHI ;速度低位 MOV BL,AH MOV CX,13 ;0000 1101b,就是设置第二数码管亮 CALL HUA CALL YANSHI ;档位 MOV BL, AL MOV CX,7 ;0000 0111b,就是设置第4个亮 CALL HUA CALL YANSHI POP BX POP AX POP DX POP CX RET PRI ENDP HUA PROC PUSH BX PUSH AX ;控制第XXX灯亮 MOV DX, MY8255_C MOV AX,CX OUT DX,AX ;B口输出CX ;输出值到数码管 MOV BH,0 MOV DX,MY8255_A MOV SI,OFFSET NUMS MOV AX,[SI+BX] OUT DX,AX ;A口输出BX,也就是NUMS[BX] POP AX POP BX RET HUA ENDP YANSHI PROC PUSH CX MOV CX,2000 YS: CALL YANSHI2 DEC CX JNZ YS POP CX RET YANSHI ENDP YANSHI2 PROC PUSH CX MOV CX,1 TYUY: DEC CX JNZ TYUY POP CX RET YANSHI2 ENDP CODE ENDS END START
实验台接法
注意实验台部分 B C 口对调,C 口低四位输入控制开关 ,所以代码需要将状态控制字改成 81 H 并且将下面的 MY8255_C 和 MY8255_B 对调
实验台效果展示
拨动 K1 K2,汽车速度为 20 km/h,档位为 2 挡
电路布线图
四位一体数码管的引脚可能会不一样,另外推荐做一个镜像图,焊板子背面的时候方便
洞洞板实物图
需要注意的是老师不让用飞线,而我嫌背面太丑用了两个飞线焊到了洞洞板的正面,所以得去掉这两个飞线,换成背面的导线
感悟
因为自己大一是电路相关专业的,有学过 C51 和 STM32 ,以及大二自己看了一点王爽的汇编,所以这次实验总体难度不大,但是周围的同学普遍对硬件有排斥的心理,而幸运的是我的队友们比较好,原意去学一下这次实验的东西。发现软工学生硬件真是一个硬伤,硬件课程少,没焊过甚至没见过电路板,感觉有点可惜