微机原理硬件实验文档格式.docx
《微机原理硬件实验文档格式.docx》由会员分享,可在线阅读,更多相关《微机原理硬件实验文档格式.docx(50页珍藏版)》请在冰豆网上搜索。
B.通过输出端口控制灯的工作状态(低电平灯亮)。
图1-1电路连接图
三、实验过程
1.在Debug下,用I是命令读输入端口的状态,即拨码开关的状态,用O命令向端口输出数据,通过发光管来查看。
测试结果:
A.使用命令:
I0E8E0H读取开关状态,得出的结果是从左到右依次增加,即
是低位,
是高位。
B.使用命令:
O0E8E0H0FEH测试发光二极管的低位(0为灯亮),即11111110B,可以看到实验板最左面的灯亮,说明二进制顺序与实验板LED灯的顺序相反,改变输入的值可依次测试各个发光二极管是否正常。
2.进入DOS,在命令行模式下输入命令debug,用a命令录入程序:
MOVDX,E8E0
MOVAL,0FEH
OUTDX,AL
MOVAH,0BH
INT21
ORAL,AL
JZ0100
INT20
输入结束后,用g命令运行,发现最右边的LED亮,其他的灯均不亮;
修改OUT输出的测试内容,再用g命令运行:
当输出位为1时,灯熄灭;
输出为0时,灯点亮。
3.分析以下程序段的作用
INT20
这一段的作用是结束程序,当程序运行的时候,系统检测到有键盘输入,则程序结束。
其中int21h是调用系统的21号中断,其使用的是0BH功能,如果没有键盘输入,则AL为0,将由JZ0100H跳转;
如果有键盘输入,AL为0FFh,则程序执行到20H时中断,结束程序。
思考题:
在使用上面录入程序的方法是,有些语句并没有写出“h”字符,这是因为系统的原因,在debug模式下,语句的读写是按照16进制进行的;
所以使用a录入命令的时候,很多语句都可以忽略后面的h字符,忽略之后依然是按照十六进制数处理。
完成上面的步骤后,在EDIT的界面内开始编写跑马灯的程序,通过编译、链接生成一个可执行文件.exe。
4.总体功能的实现
开关
端口位置(从左到右)
置1(拨码开关向上)
置0(拨码开关向下)
无
LED灯的顺序反序,使二进制LED灯顺序和拨码开关上下位置相对应
S0
1
关闭程序,返回DOS
程序正常运行
S1
2
循环右移
循环左移
S2
3
暂停
正常循环
S3
4
慢速
快速
S4
5
三个灯同时亮
只有一个灯亮
5.流程图
图1-2流程图
6.程序源代码
DATASEGMENT
SWSTATEDB0;
存放当前拨码开关的状态
LDSTATEDB0FEH;
要输出到I/O口的LED灯状态
BUFFERDB0
DATAENDS
STACKSEGMENTSTACK'
STACK'
DB100HDUP(0)
STACKENDS
CODESEGMENT
ASSUMEDS:
DATA,SS:
STACK,CS:
CODE
;
----------------------------------------------------主程序----------------------------------------------------
MAINPROC
PUSHDS
XORAX,AX
PUSHAX
MOVAX,DATA
MOVDS,AX
movdx,0e8e0h
inal,dx;
读出八个开关的状态
movbl,al
movbh,al
movcx,08h
ll:
salbl,1;
这个循环用来把al的八位顺序调换过来
rcral,1
loopll
xoral,0ffh;
把AL反相,因为LED灯亮的0、1逻辑与拨码开关的逻
辑相反
outdx,al;
输出反相后的灯的状态,将灯变为左低右高
MOVLDSTATE,0FEh;
初始化灯的状态为11111110B,0为灯亮,对应最右面
灯亮
CALLINF;
调用INF
RET
MAINENDP
;
--------------------------------------------------主程序结束-----------------------------------------------------
-------------------------------------------反复实现走马灯功能的子程序--------------------------------------
INFPROC;
实现一直循环进行闪烁的功能
INFLOOP:
CALLREPEAT
JMPINFLOOP
INFENDP
REPEATPROC;
重复检测拨码开关的状态,实现相应的功能
CALLREAD;
读入拨码开关的状态
CALLDIRECTION;
循环方向检测
CALLMODE;
灯亮的模式检测
CALLPAUSE;
测试是否暂停
CALLCLOSE;
测试是否关闭
CALLSPEED;
测试速度选择
REPEATENDP
----------------------------------------------延时子程序------------------------------------------------------
DELAYPROC
PUSHCX
MOVCX,1000H;
外循环1000H次
LOOP1:
MOVCX,8000H
LOOP2:
DECCX
JNZLOOP2;
内循环8000H次
POPCX
JNZLOOP1
DELAYENDP
---------------------------------------读取拨码开关状态的子程序-------------------------------------
READPROC
PUSHAX
PUSHDX
MOVDX,0E8E0H;
通过0E8E0H端口读取
INAL,DX
MOVSWSTATE,AL;
SWSTATE用来存储当前拨码开关状态
POPDX
POPAX
READENDP
---------------------------------------------改变LED灯的亮灭的子程序-----------------------------------
WRITEPROC;
改写LED灯的状态
MOVAL,LDSTATE;
LDSTATE存放有LED灯的状态
MOVDX,0E8E0H
OUTDX,AL;
通过0E8E0H端口写给LED灯,控制灯的亮灭
WRITEENDP
-------------------------------------------关闭功能测试-------------------------------------------------
CLOSEPROC
TESTSWSTATE,01H;
和00000001B相与,若S0为1,则说明关闭程序
JZEXIT
CALLRETURN
EXIT:
CLOSEENDP
RETURNPROC
MOVAL,1;
返回DOS时,最终的状态灯全部关闭
MOVDX,0E8E0H
OUTDX,AL
MOVAX,4C00H
INT21H
RETURNENDP
-------------------------------------------测试灯亮方向的子程序--------------------------------------------
DIRECTIONPROC
TESTSWSTATE,02H;
如果S1置位1,则结果不为0,循环右移
JZLEFT
RORLDSTATE,01H
LEFT:
ROLLDSTATE,01H;
无外部控制,则循环左移
EXITDIR:
DIRECTIONENDP
-------------------------------------------测试是否暂停的子程序--------------------------------------------
PAUSEPROC
BEGIN:
CALLREAD
TESTSWSTATE,04H;
测试S2,S2=1表示暂停,则一直检测,直到S2=0
JNZBEGIN
PAUSEENDP
--------------------------------------------测试速度控制的子程序-----------------------------------------
SPEEDPROC
CALLDELAY
TESTSWSTATE,08H
JZFAST;
检测S3的状态,S3=0表示快速灯亮
CALLDELAY;
S3=1表示慢速灯亮,调用延时子程序
CALLDELAY
FAST:
SPEEDENDP
-----------------------------------------测试灯亮模式的子程序-------------------------------------------
MODEPROC
PUSHWORDPTRLDSTATE;
保护原来的LED灯状态,当灯亮模式由”三个灯
同时亮”变回”单灯模式”时,保证不会出错
TESTSWSTATE,10H;
检测S4的状态,若置位1,则改为3个灯同时亮
JZSINGLE;
如果与的结果为0,说明没有外部置位,转为单灯循环
PUSHBX
MOVAL,LDSTATE
MOVBL,AL;
注意到LED灯亮灭逻辑是:
0则灯亮,1则灯灭
所以通过左移一位然后与原LED状态相与,使得新的一位也复位0,又一盏灯亮
ROLBL,1
ANDBL,AL
MOVCL,BL
ROLCL,1
ANDAL,CL;
此时已经LDSTATE已经有连续3位为0了
MOVLDSTATE,AL;
改写灯的状态
POPCX
POPBX
POPAX
SINGLE:
CALLWRITE;
调用WRITE改写LED灯的状态
EXITMODE:
POPWORDPTRLDSTATE
MODEENDP
CODEENDS
ENDMAIN
四、实验结果
编译、连接后,上述功能均实现,可以调节走马灯的速度、模式、方向、暂停、返回DOS,且返回DOS后,所有的LED灯均熄灭。
五、实验总结
问题1:
刚开始编写实验代码的时候忽略了退出程序部分代码的编写,因此开始时每运行一
次程序都得重新启动计算机一次。
解决:
利用系统的21号中断的0b号功能实现系统中断,程序结束。
问题2:
第一次写这个程序的时候,当关闭系统后,LED灯还是亮着,十分不符合实际情况。
通过在返回DOS之前加入一小段程序,使得LED灯全都置位,对应着LED灯全都灭了。
六、思考题
Ø
有些语句并没有写出“h”字符,这是因为系统的原因,在debug模式下,语句的读写是按照16进制进行的;
七、实验收获与心得体会
在第一次的微机原理硬件实验中,学会了基本的测试实验板上器件的方法、I/O端口的读进与写出、拨码开关以及LED灯‘0’所表示的状态、接口地址等,这些基本的知识是以后试验最基本的应用,应熟练掌握和使用。
在实验过程中,在第一次实验课期间,编写代码时只考虑到了最基本的循环闪烁的功能,而主要的代码放在了如何将led灯的位置转变为正常人感觉的位置(二进制最低位LED灯在实验板的最右边,想转为最左边,与拨码开关的位置上下位置一致),所以第一次验收就只有一个循环右移的功能,而没有其他任何功能,所以课后又加入了一些功能,好在老师给了我们又一次的验收机会,让我们组完整的完成了实验,感谢老师在我们编写过程中的指导和帮助。
还有要注意的就是在子程序使用通用寄存器的时候,一定要先入栈保护,使用完出栈,以防对其他子程序造成数值的改变,后果较为严重。
本次实验让我们学会基本的微机原理硬件知识,也学会了如何调试代码,对书本上知识的理解地更加深刻,有一些没学到的课本知识也通过本次实验提前了解和运用,效果很好。
实验二8255A并行接口应用
1.掌握8255A的功能及方式0、1的实现。
2.熟悉8255A与CPU的接口,以及传输数据的工作原理及编程方法。
3.了解七段数码管显示数字的原理。
4.掌握同时显示多位数字的技术。
1.查找八段数码管的显示规律及数码管的位选规律。
2.六位数码管静态显示。
在数码管电路上静态地显示6位学号,当主机键盘按下任意键时,停止显示,返回DOS。
3.六位数码管动态显示。
要求在数码管电路1-6位数码管上,动态显示6位学号,当主机键盘按下任意键时结束。
4.扩展部分:
完成扫描键盘(PC口)输入自己的学号,并在数码管上显示。
图2-1电路连接图
3、实验过程
1.八段数码管位选规律
在方式0(输入/输出)下,以A口为输出口,B口为输出口,A口接六个共阴极数码管的八位段码,高电平点亮数码管的某一段,B口接数码管的位选(即要使哪个数码管亮),高电平选中某一位数码管点亮。
测试结果如下图所示。
由此,容易得出数字0~9以及字母A~H的编码,如下表所示。
字形
6
7
编码
0EDH
21H
0F4H
0F1H
39H
0D9H
0DDH
61H
8
9
A
B
C
D
E
F
0FDH
0F9H
7DH
9DH
0CCH
0B5H
0DCH
5CH
2.六位数码管静态显示
在数码管电路上静态地显示6位学号,当主机键盘按下任意键时,停止显示,返回DOS。
该电路6个数码管的同名阳极段已经复接,当段选寄存器寄存了一个字型编码之后,6个数码管都有可能显示出相同的数字。
如果要使6个数码管“同时”显示不同的数字,必须采用扫描显示的方法,通过选位寄存器选择某一位数码管,显示其数字(对应段值为1),然后关闭此数码管,再选择下一位数码管进行显示;
如果在一秒钟内,每一位数码管都能显示30次以上,则人眼看到的是几位数码管同时在显示。
实验证明,在扫描显示过程中,每一位显示延迟1ms是最佳选择。
在本次实验中,通过反复循环扫描6个数码管,使数码管显示数字,每次扫描过后检测主机键盘输入的状态,若有按键按下,则返回DOS。
程序框图:
图2-2第一个实验的流程图
程序代码:
DATASEGMENT
NUMDB0F4H,21H,0EDH,0F1H,0FDH,0F1H;
学号210383对应的数码显示译码
DB100DUP(0)
STACKENDS
ASSUMECS:
CODE,DS:
DATA,SS:
STACK
----------------------------------------------------主程序-------------------------------------------------------
START:
MOVAL,10000000B
MOVDX,0E803H
OUTDX,AL;
8255写入工作方式控制字
MOVAX,DATA
MOVDS,AX
MOVES,AX
LOOP1:
XORSI,SI;
SI=0
MOVCX,06H;
扫描6个数码管
MOVDX,0E800H;
数码段选端口
MOVBL,00000001B;
BL暂存了数码管的位选信息
LOOP2:
MOVAL,NUM[SI];
输入学号的第一个数字
OUTDX,AL;
显示数字
MOVAL,BL
INCDX
控制选择某一个灯亮
DECDX
ROLBL,1;
左循环1位,下次就是下一个LED灯亮了
INCSI
CALLDELAY;
延时,达到视觉暂留的效果
CALLIFIN;
检测是否有主机按键输入
LOOPLOOP2;
一直循环,直到显示完所有的数字
JMPLOOP1
---------------------------------------------------延时子程序--------------------------------------------------
DELAYPROCNEAR
PUSHBX;
使用通用寄存器前要先入栈保护
MOVBX,0002H;
外循环为2,控制循环时间
LOOP3:
MOVCX,0H;
内循环开始为0FFFFH,最大值
LOOP$
DECBX
JNZLOOP3;
如果没有循环完毕则一直循环
POPBX
-------------------------------------------------检测主机键盘输入-----------------------------------------
IFINPROCNEAR
PUSHAX;
MOVAH,0BH;
检测键盘输入
INT21H
ORAL,AL
JZLOP;
如果主机没有按键输入,则继续进行显示学号
MOVAH,4CH;
当有主机键盘输入,则返回DOS
LOP:
POPAX
IFINENDP
ENDSTART
3.六位数码管动态显示
①本实验应在上面六位数码管静态显示的实验基础上完成,包含了静态显示的核心代码,增加的是要在一定的时间间隔内去移位读取“HELLO”字符串中需要显示的部分,即有6种静态显示的状态,需要每隔一段时间显示一种静态状态,最后可达到动态显示的目的。
②在数据段,按下列规律设置12个字型码:
MESGDB0,0,0,0,0,0,3DH,0DCH,8CH,8CH,0EDH,0
POINTDWMESG
……
POINT单元存放MESG单元的有效地址,程序取出POINT单元的内容→BX,然后用BX间址取数送数码管电路,扫描显示6个字符。
每过0.5s将POINT单元的内容加1,再将POINT单元的内容→BX,……。
POINT单元内容加1,使字符串显示的首地址向高地址移动一个单元,从而使6位字符串向“左”移动一位,实现动态显示。
③可通过读取拨码开关S0/S1/S2的状态控制动态显示速度变慢,即增加延时,利用实验一读入端口的功能。
图2-3第二个实验的流程图
DATASEGMENT
NUMDBDB0,0,0,0,0,0,3DH,0DCH,8CH,8CH,0EDH,0;
”hello”字符串对应的数码译码
CSCDB01H,02H,04H,08H,10H,20H;
六个数码管位选
ADPDW0E801H;
位选端口地址
ADWDW0E800H;
段选端口地址
DB100DUP(?
)
ASSUMECS:
CODE,SS:
STACK,DS:
DATA
-----------------------------------------------------延时子程序---------------------------------------------------------
DELY;
精确延时
PROCNEAR
PUSHAX;
所有通用寄存器入栈保护,保护现场
PUSHSI
MOVCX,0
MOVDX,1000
MOVAH,86H
INT15H
POPSI;
恢复现场
POPAX
DELYENDP
----------------------------------------------主程序--------------------------------------