微机原理硬件实验二:数码管动态显示

北邮微机原理硬件实验二,8255A并行接口应用。基于8086的汇编编程实现。
嗯,已经第二次实验了。第一次实验看了学长的代码,已经学到不少东西了,这一次该自己好好写了!

实验要求

简要说明

在方式0(输入/输出)下,以A口为输出口,B口为输出口, A口接六个共阴极数码管的八位段码,高电平点亮数码管的某一段, B口接数码管的位选(即要使哪个数码管亮),高电平选中某一位数码管点亮。

8255A中    A端口地址    EE00H
B端口地址    EE01H 
C端口地址    EE02H
控制地址    EE03H

八段数码管的显示规律及数码管的位选规律自己查找,可用实验一中,学过的I、O命令来做。

6位数码管静态显示

在数码管电路上静态地显示6位学号,当主机键盘按下任意键时,停止显示,返回DOS。提示:该电路6个数码管的同名阳极段已经复接,当段选寄存器寄存了一个字型编码之后,6个数码管都有可能显示出相同的数字。如果要使6个数码管“同时”显示不同的数字,必须采用扫描显示的方法,通过选位寄存器选择某一位数码管,显示其数字(对应段值为1),然后关闭此数码管,再选择下一位数码管进行显示;如果在一秒钟内,每一位数码管都能显示30次以上,则人眼看到的是几位数码管同时在显示。
实验证明,在扫描显示过程中,每一位显示延迟1ms是最佳选择。

6位数码管动态显示

要求在数码管电路1-6位数码管上按图3.2所示的规律,动态显示字符串HELLO,当主机键盘按下任意键时结束。
提示:
①本实验应在上面实验的基础上完成
②在数据段,按下列规律设置12个字型码:

MESG    DB   0,0,0,0,0,0,3DH,0DCH,8CH,8CH,0EDH,0
POINT    DW   MESG
…   …

POINT单元存放MESG单元的有效地址,程序取出POINT单元的内容→BX,然后用BX间址取数送数码管电路,扫描显示6个字符。每过0.5s将POINT单元的内容加1,再将POINT单元的内容→BX,……。POINT单元内容加1,使字符串显示的首地址向高地址移动一个单元,从而使6位字符串向“左”移动一位,实现动态显示。
③动态显示的速度可控制(快或慢),利用实验一读入端口的功能

编程思路

要干掉这么一坨东西,还真是很头痛。
实验一已经学习过怎么对程序进行分块了,也知道如何使用变量了。
要实现6个数显管“同时显示数字”,出于节省引脚的考虑,我们也只能运用时分复用,每次只亮一个数显管,显示该数显管的数字,然后切换到下个数显管显示下一个数字,当扫频速度足够快时,就可以做出“同时显示”的效果了。嗯,各种实验都做过很多次数显管显示了,网上也有很多资料,不累赘了。
本实验还要使用8255A用作输出,可以下载到它的Data Sheet用作参考。
伪代码:

int main()
{
	initialize();
	while(1){
		read_switch(); // Read switch state.
		out_cat(); // Turn the next ONE Nixie-tube on.
		out_led(); // Display the current number.
		delay(); // Have some delay.
		return_to_DOS(); // Check if switch state acquires exit.
	}
	return 0;
}

源代码

; Exercise 2: Nixie_tube Display
; AUTHOR: feichashao
; DATE: 2013-12-7

DATA SEGMENT
CatState DB 01H
STUDENT DB 00H,0F4H,21H,0EDH,0F1H,61H,61H,00H
HELLO DB 00H,03DH,0DCH,8CH,8CH,0EDH,00H,00H
DIGIT DB 00H
COUNT DW 0000H
SwState DB 0
DATA ENDS

STACK SEGMENT STACK 'STACK'
    DB 100 DUP(?)
STACK ENDS

CODE SEGMENT
    ASSUME CS:CODE,DS:DATA,SS:STACK

Main PROC
    PUSH DS
    XOR AX,AX
    PUSH AX
    MOV AX,DATA
    MOV DS,AX
    MOV CatState,1H
    MOV DIGIT,1H
    CALL Initialize
    CALL EndlessRepeat
    RET
Main ENDP

Initialize PROC
    PUSH DX
    PUSH AX
    MOV AL,80H
    MOV DX,0E803H
    OUT DX,AL
    POP AX
    POP DX
    RET
Initialize ENDP

EndlessRepeat PROC
EndlessLoop: CALL ProcToRepeat
    JMP EndlessLoop
    RET
EndlessRepeat ENDP

ProcToRepeat PROC
    CALL readSw
    CALL outCat
    CALL outLED
    CALL excuteDelay
    CALL returnToDOS
ProcToRepeat ENDP

readSw PROC
    PUSH AX
    PUSH DX
    MOV DX,0E8E0H
    IN AL,DX
    MOV SwState,AL
    POP DX
    POP AX
readSw ENDP

DivFreq PROC
    PUSH CX
    MOV CX,0100H
MyLoop: PUSH CX
    MOV CX,0800H
MyNestedLoop: DEC CX
    JNZ MyNestedLoop
    POP CX
    DEC CX
    JNZ MyLoop
    POP CX
    RET
DivFreq ENDP

outCat PROC
    CMP COUNT,00FFH
    JZ MOVECAT
    ROL CatState,01H
    PUSH DX
    PUSH AX
    MOV AL,CatState
    MOV DX,0E801H
    OUT DX,AL
    POP AX
    POP DX
    RET
MOVECAT: ROL CatState,01H
    ROL CatState,01H
    MOV COUNT,0000H
    RET
outCat ENDP

outLED PROC
    INC DIGIT
   ; TEST DIGIT,06H
    CMP DIGIT,08H
    JNC CLEAR
    PUSH DX
    PUSH AX
    PUSH BX
    MOV BL,DIGIT
    MOV BH,0H
    
    TEST SWSTATE,01H
    JNZ printHello

    MOV AL,STUDENT[BX]
    MOV DX,0E800H
    OUT DX,AL
    POP BX
    POP AX
    POP DX
    RET

printHello: MOV AL,HELLO[BX]
   ; MOV AL,DS:[BX]
    MOV DX,0E800H
    OUT DX,AL
   ; MOV DX,0E8E0H
   ; OUT DX,AL
    POP BX
    POP AX
    POP DX
    RET
CLEAR: MOV DIGIT,00H
    RET
outLED ENDP

excuteDelay PROC
    CALL DIVFREQ
    TEST SWSTATE,01H
    JZ exitDelay
    INC COUNT
exitDelay:    RET ; Do Nothing this time.
excuteDelay ENDP

returnToDOS PROC
  TEST SWSTATE,02H
  JZ exitReturnToDOS
  CALL exereturnToDOS
exitReturnToDOS: RET
returnToDOS ENDP

exereturnToDOS PROC
  MOV AX,4C00H
  INT 21H
exereturnToDOS ENDP

CODE ENDS
END MAIN

数显管亮灭控制

控制6位数显管的亮灭,1为亮,0为灭。
我们可以用一个8bits的变量,来记录和控制这6位数显管的状态。
初始状态

CatState DB 00000001B

要显示下一个数字的时候,只要对CatState进行左移一位就可以了。
但是,这个数据是8位的,但实际只显示6位,所以学号的数据一定要有8位,填充两个无意义的字符即可。
(前后的00H都是不显示的,占个坑就好。)

STUDENT DB 00H,0F4H,21H,0EDH,0F1H,61H,61H,00H

动态显示“HELLO”

要求显示的“HELLO”看上去是移动的。
实现的方法其实很简单,只要每隔1秒,将数显管的控制变量CatState多移动一位就好,其他的还是按原来的样。

吐槽

上课之前,碰到一女生。她实验一的代码,是自己写的。(天啊,这是什么一个时代,抄袭代码竟然是常态。)
然后她上周的实验,辛辛苦苦写了半天代码,却因为功能不全,而得了低分。
像我这些,直接挪用学长代码,三下两下完成实验的,却得了高分。
所以她说,这次实验就改用别人代码了。
大学教育就是这么引导的?
我也因为这个实验没有按时完成,被老师不爽了一下。
不爽就不爽吧,反正学到的是自己的。