8086微机汇编实验报告

更新时间:2023-12-07 16:53:01 阅读量: 教育文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

电梯模拟实验

一、 实验目的

通过综合实验使学员复习并熟练掌握各个模块电路功能、基本原理、线路连接和驱动方法。自己编写嵌入式代码进行驱动,掌握相关的程序设计、电路测试的基本能力。通过动手实践进一步加深对理论知识的理解,提高动手能力。

二、 实验原理

1. 使用模块:

本实验使用了8254、8255、七段数码管、4*4键盘、步进电机、喇叭6大模块来进行模拟电梯的综合实验。 2. 连接电路:

(1).使用8255的C口的PC0~PC7连接4*4键盘的行3~列0,接收4*4键盘输入;

(2).将8255的A口PA0~PA7分别与七段数码管的段码驱动输入端a~dp相连,位码驱动输入端S0接+5V,S1~S3接GND,编程实现在其显示电梯所处的楼层; (3).使用8255的B口的PB0~PB3分别与步进电机的驱动输入端BA~BD相连,编程实现根据键盘输入实现顺时针(反时针)转动;

(4).8254的CLK0接1MHz时钟,GATE0接8255的PB5,OUT0和8255的PB4分别接与门的两个输入端A和B,与门输出端Y连接喇叭,编程实现电梯到达所要求的楼层后发出设定的声音进行提示,具体实验电路如下图.

3. 接线:

PC7~PC0/8255 PA7~PA0/8255 +5V GND PB3~PB0/8255 CS/8255 CS/8254 1M时钟 PB5/8255 PB4/8255 OUT0/8254 喇叭 4. 程序流程

接 接 接 接 接 接 接 接 接 接 接 接 行3~列0/4*4键盘 dp~a/LED数码管 S0/LED数码管 S3~S1/LED数码管 BD~BA/步进电机 Y1/IO地址 Y0/IO地址 CLK0/8254 GATE0/8254 B/与门 A/与门 Y/与门

三、 关键点及难点

1.关键点

(1).8255的控制方式

8255是通用并行接口芯片,但在具体应用时,要根据实际情况选择工作方式,连接硬件电路(外设),待进行初始化编程之后才能成为某一专用的接口电路。8255的初始化编程比较简单,只需要一个方式控制字就把3个端口设置完成。方式控制字决定端口A、B和C的工作方式,如下图所示。

(2).I/O端口值的读写

实验中,会对大量的I/O端口进行读写操作,我们通过I/O端口对相关的硬件进行数据的读写,在进行数据读写的过程中,要清楚相关的函数操作以及写入的bit位的值对硬件起到怎样的控制。下面是C语言方式对I/O端口读写进行操作的相关函数: 函数名 PortReadByte PortWriteByte 语 法 BOOL PortReadByte(DWORD BOOL PortWriteByte(DWORD address, BYTE *pdata) address, BYTE data) 功 能 读该卡某个的I/O端口值 将给定值写入该板所指的I/O端口 参 数 address:指明要读的I/O端口地address:指明要读的I/O端口址 地址 pdata:该函数执行完后,data:该函数执行完后,data被address所指的端口值被填入该写入address所指的I/O端口 地址 返回值 成功:返回True 成功:返回True 失败:返回False 失败:返回False

(3).七段数码管工作原理

实验所用的七段数码管为共阴型,段码采用同相驱动,输入加高电平,选中的数码管亮,位码加反相驱动器,位码输入端高电平选中。七段数码管的字型代码表如下表: 显示字型 g e f d c b a 段码 字型f实例 0 0 1 1 1 1 1 1 3fH e=1 f=1 a=1 d=0 g=1 b=0 c=0 段码:71H 1 2 3 4 5 6 7 8 9 a b c d e f 0 1 1 1 1 1 0 1 1 1 1 0 1 1 1 0 0 0 1 1 1 0 1 1 1 1 1 0 1 1 0 1 0 0 0 1 0 1 0 1 1 1 1 1 1 0 1 1 0 1 1 0 1 1 0 1 1 1 1 0 1 0 1 1 1 1 1 1 1 1 1 0 1 0 0 1 1 1 1 0 0 1 1 1 1 0 0 1 0 0 1 1 1 0 1 1 1 1 1 1 0 1 0 1 1 06H 5bH 4fH 66H 6dH 7dH 07H 7fH 6fH 77H 7cH 39H 5eH 79H 71H 2. 难点

(1).端口复用的问题

电梯模拟实验中,使用了七段数码管来显示电梯所处的楼层,步进电机的正反转动相应的角度来模拟电梯的上升和下降,由于数码管占用了PA口的7位,步进电机需要4位,喇叭需要2位,一开始由于只是从基本实验中复用代码,只用到了8255的A口输出和C口输入,数码管、步进电机、喇叭都接在了A口,调试代码的时候发现,各硬件模块并不能按预期的那样运作,总是一下子正常一下子不正常,或者直接保持一个状态不变。

通过认真的阅读代码和研究8255的端口操作,发现是端口复用造成的相互干扰。例如用A口驱动数码管,使其显示某一数字,接着再用A口驱动步进电机,那么数码管的状态就会被改变,显示的数字就会变化。端口复用造成各模块相互影响,为了解决这个问题,我认真查阅了8255的基本原理和工作方式,最后通过重新设置8255的控制字,使其A口和B口均为输出端口,这样就有16位用来接线,就可以满足实验的要求。

(2).嵌入式程序调试

汇编语言的机器代码生成效率很高,但可读性并不强,复杂一点的程序就更难读懂而且费时费力,而C语言在大多数情况下其机器代码生成效率和汇编语言相当,但可读性和可移植性却远远超过汇编,可以缩短开发周期,更容易调试,所以本实验我们选择用C语言写代码。但是对于硬件开发,C语言一般要提供相应的库,一开始并看不懂基本实验的C语言代码,尤其是Startup、PortReadByte、PortWriteByte、Cleanup函数,所以我去查阅学生实验指导书上面的相关函数说明,结合课上教员所讲的理论知识和书上讲解,才弄明白其实现的功能和原理。 同时在代码写完后,进行调试,发现程序执行之后各模块开始运行,但是一断电重启又得在PC端重新执行程序,这与我之前玩51单片机、arduino、树莓派有点区别,他们是将程序烧录之后重启之后依然能运行,掉电信息不丢失。所以我猜该实验平台是通过USB接口与PC端通信,实时接收PC端传送的数据;并且通信的稳定性不太好,表现为有时PC端的程序还在执行,硬件模块却停在某

一状态不动了。可能原因可能是人体带电或者有导电的物体落在了实验电路上,造成通信干扰或中断,这种一般重启电路并且重新运行程序就好了。

(3).实验箱本身存在问题

在第一次进行基本实验中的电子琴实验时,按照学生实验指导书上的说明连线,打开程序代码,编译、构建、执行,按相应的按键,发现试验箱上的喇叭毫无反应,然后反复检查连线,发现并没有问题。这时,我们组怀疑是喇叭坏了,通过把与门的Y与LED灯模块中的一个LED连接,发现有电压输出,所以我们更加确信是喇叭坏了。然后我们换了一个试验箱,进行相同的实验,成功了;在实验中,我们不能保证电路、各电子元件都是正常的,遇到问题要找到原因和解决办法。一般在检测电路时,我们会用到万用表、示波器等工具,但有时可以用LED灯(发光二极管)是否发光来检测电流的流向,即电源的正负,用快速的试触来检测是否有电压。(当然,LED不亮的原因可能是小于最低发光电压或反接了)

(4).备份和记录

由于实验中会遇到各种问题,之前写好的代码可能没保存,改了之后又忘了之前;所以一定要及时备份相关的代码及资料。还有,实验过程中遇到的问题要及时记录,下次就可以提供参考来避免类似的问题,还可以用来交流经验。最重要的是实验的原理、电路的连接一定要记录下来,因为每隔一个星期才做一次实验,非常容易忘记上次实验的进度和细节。

四、 关键代码清单

函数名:de_lay 功能:延迟函数

参数:低位i,高位j

代码清单4-1de_lay()

void de_lay(unsigned short i,unsigned short j) {

PortWriteByte(0x280,i); /*输出计数值低位*/ Sleep(50);

PortWriteByte(0x280,j); /*输出计数值高位*/ }

函数名:voice

功能:电梯到达后,声音提示 参 数:无

代码清单4-2voice()

void voice() {

PortWriteByte(0x283,0x36);/*00010110,8253控制字,分高低位传送*/ Sleep(10);

de_lay(time[0x37-0x31],time1[0x37-0x31]); Sleep(10);

PortWriteByte(0x28b,0x80);/*10000000,8255控制字*/ Sleep(10);

PortWriteByte(0x289,0x30);/*设置8255B口,开扬声器*/ Sleep(200); /*延时*/

de_lay(time[0x32-0x31],time1[0x32-0x31]); Sleep(100);

PortWriteByte(0x289,0x00);/*设置8255B口,关扬声器*/ }

函数名:main(主函数)

功 能:通过4*4键盘进行楼层的输入,电梯通过对当前所处楼层的比较,选择上升或下降或不动(步进电机顺时钟转或逆时钟转动或不动),数码管实时显示电梯所处的楼层,当电梯到达后,数码管和步进电机停止运行,同时喇叭发声进行提示。 参 数:无

代码清单4-3 main()

void main() {

/*打开设备*/ if(!Startup()){

printf(\ return; }

printf(\

PortWriteByte(0x28b,0x89); /*设置8255控制字*/ j=16;

while(!kbhit()){ n=j;

/*电梯上升,电动机顺时针转动*/ if(n>temp){ buf=0x33;

for(t=temp;16>t&&n>=t;t++){

PortWriteByte(0x288,led[t]); Sleep(1000);

buf = ((buf&1)<<7)|(buf>>1); PortWriteByte(0x289,buf&0x0f); }

voice(); }

/*电梯下降,电动机逆时针转动*/ else if(n

for(t=temp;n<=t;t--){

PortWriteByte(0x288,led[t]); Sleep(1000);

buf = ((buf&128)>>7)|(buf<<1); PortWriteByte(0x289,buf&0x0f); }

voice(); } else

PortWriteByte(0x288,led[j]); /*temp保存当前电梯所处楼层*/ temp=j;

/*接收按键数据,即前往的楼层*/ PortWriteByte(0x28a,0x0f); PortReadByte(0x28a,&data); i=data;

if (i!=0x0f){ i=data; Sleep(50);

PortWriteByte(0x28a,0xf0); PortReadByte(0x28a,&data); i=i|data;

if (i==0x77) j=0; else if(i==0x7b) j=1; else if(i==0x7d) j=2; else if(i==0x7e) j=3; else if(i==0xb7) j=4; else if(i==0xbb) j=5; else if(i==0xbd) j=6; else if(i==0xbe) j=7; else if(i==0xd7) j=8; else if(i==0xdb) j=9; else if(i==0xdd) j=10; else if(i==0xde) j=11; else if(i==0xe7) j=12; else if(i==0xeb) j=13; else if(i==0xed) j=14; else if(i==0xee) j=15; else;

}

} }

/*关闭设备*/ Cleanup();

代码清单4-4头文件

#include #include #include \

#pragma comment(lib,\

代码清单4-5全局变量

byte data,n; /*保存4*4键盘输入的数据,即输入的楼层*/ byte i,j,t;

byte temp=0; /*保存电梯当前所处的楼层*/ int buf=0x33; /*驱动步进电机*/ /*从0-f对应的段码表*/

char led[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,

0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x00};

本文来源:https://www.bwwdw.com/article/g67t.html

Top