微机实验报告.docx

上传人:b****8 文档编号:8996718 上传时间:2023-02-02 格式:DOCX 页数:20 大小:76.52KB
下载 相关 举报
微机实验报告.docx_第1页
第1页 / 共20页
微机实验报告.docx_第2页
第2页 / 共20页
微机实验报告.docx_第3页
第3页 / 共20页
微机实验报告.docx_第4页
第4页 / 共20页
微机实验报告.docx_第5页
第5页 / 共20页
点击查看更多>>
下载资源
资源描述

微机实验报告.docx

《微机实验报告.docx》由会员分享,可在线阅读,更多相关《微机实验报告.docx(20页珍藏版)》请在冰豆网上搜索。

微机实验报告.docx

微机实验报告

东南大学自动化学院

实验报告

课程名称:

微机实验及课程设计

实验名称:

出租车自动计价器

院(系):

自动化学院专业:

自动化

姓名:

学号:

实验室:

实验组别:

同组人员:

实验时间:

年月日

评定成绩:

审阅教师:

目录

一.课程设计目的与要求……………………………………………3

二.方案论证与原理设计……………………………………………3

三.详细设计…………………………………………………………4

四.方案实现及测试………………………………………………5

五.分析与总结………………………………………………………8

一.课程设计目的与要求(含设计指标)

1、课程目的

(1)巩固已学的微机原理与接口的基本知识;

(2)训练自己分析问题解决问题的能力;

(3)为出租车设计一个自动计价器。

2、基本要求

设计一个出租车自动计价器,计费包括起步价、行车里程计费、等待时间计费三部分,用三只数码管显示总金额,最大值为99.9元,起步价8.0元,3公里之内按起步价计费,超过3公里,往返双程可设每1公里1.2元,单程每公里2.4元,等待时间每分钟0.2元。

用两位数码管显示总里程数,最大值99km,用两位数码管显示等待时间(分钟),最大值99分钟。

假设里程数与脉冲个数成正比,每km脉冲数100个(可设定),低于每小时5公里时间同等待状态。

(1)假设有计数比较器测定停车与行车状态,转换成开关信号。

开关输入行车状态,并用LED灯显示;同时又空车信号,可用于启动计价并用LED灯显示;

(2)记录里程数,等待时间,计算总金额,并实时显示;

(3)模拟刹车和启动动作,动作后立即停车/行车;

(4)简单的标定和检错功能。

3、设计指标:

(1)采用二型键盘式数码管,采用扫描方式进行显示。

头两位显示价格,中间两位显示里程,最后两位显示等待时间

(2)计费标准见基本要求

(3)用开关来模拟所有行车状态,用直流电机产生的信号来模拟速度。

二.方案论证与原理设计(或基本原理)

1、整个设计思路

在内存中已经存好每公里对应的费用和每分钟对应的费用,然后根据所记的里程数和时间查询得到应该有的费用,然后进行操作。

出租车行驶的时钟采用内部定时,而等待的时钟则采用8253进行精确定时。

主控模块:

首先判断出租车的状态是行驶还是停止,若是停止,则调用停止模块,出租车将静止记时和费用累加;若是行驶,则调用运动模块,判断出租车是单程行驶还是双程行驶,然后相应调用运动模块,对里程数进行累加和费用累加;

显示模块:

显示模块分为2个小模块,第一个小模块把放到内存的费用单元、里程单元和时间单元的值掉到显示缓冲区中,第二个小模块将显示缓冲区中的数通过数码管显示出来;

费用累加模块:

费用累加模块的功能是把行驶的费用与等待的费用累加,并把16进制数转换成压缩BCD码,以符合现实的格式;

2、数码管显示原理:

先要预置数码管的段码如下(只显示数字0-9):

leddb3fh,06h,5bh,4fh,66h,6dh,7dh,07h,7fh,6fh;

各数码管的实际段码存储在固定的内存单元buffer中,共占2个单元,执行显示子程序时,根据位码的选择,从对应的单元中取出段码输出,但需要修改段码时,直接对相应的存储单元进行操作。

根据上面的原理设计,整个系统可以由主程序、费用累加子程序、显示子程序等几部分组成。

做出系统的程序流程图如下所示:

三.详细设计

1、在程序的数据段里定义好8253、8255各需要用到的端口地址,定义数码管的段码和位码地址;还有版权信息,数码管的预存段码值和实际段码值以及与中断有关的一些信息等等。

2、硬件设计:

主要用到8253,8255,七段数码管和6个开关。

8253的作用是精确定时,由于等待每1分钟需要改变记录时间和费用,所以这1分钟需要定时计数。

8253采用串联连接方式。

通道0的初始化是:

先读/写低字节,后高字节,方式2,BCD计数。

初值是0000h;而通道1的初始化是先读/写低字节,后高字节,方式4,BCD计数,初值是6000h。

8253的输出是一个低脉冲,然后8255捕捉到这个低脉冲,就触发,时间加1且费用作出相应的改变。

8255主要用到PA口、PB口和PC口。

PA口的作用是输出七段数码管的段码,从而使七段数码管显示出相应的数据。

PB口是输出七段数码管的位码,从而控制两管的其中一管亮;PC口的作用是输入6个开关传递过来的控制信号和8253传递过来的定时信号;

6个开关的作用分别是:

K0是使数码管显示时间;K1是使显示里程;K2是显示费用的低两位(如123.4元就显示34);K3是显示费用的高两位(如123.4元就显示12);K4是运动/静止测试位,如果K4为1,则表示出租车运动,为0则表示出租车静止;K5是指出租车的运动选择,若为1,则是单程,为0为双程;下面是主要硬件连接图:

四.方案实现与测试(或调试)

1、数码管显示程序主要代码

dispprocnear

movdi,offsetbuffer1

loop2:

movbh,02

test_it:

movdx,io8255d;然后利用C口判断究竟给buffer1赋什么值,赋值子程序

inal,dx

testal,01h;如果C口读到D0=1,则跳转到时间显示模块

jnztime

testal,02h;如果C口读到D1=1,则跳转到历程显示模块

jnzdis

testal,04h;如果C口读到D2=1,则跳转到费用1(个位十位)显示模块

jnzmon1

testal,08h;如果C口读到D3=1,则跳转到费用2(千位百位)显示模块

jnzmon2

time:

movsi,offsettimes

moval,[si]

calltran;数值转换,将16进制数转换成压缩型BCD码

calldisp1

jzlll

dis:

movsi,offsetdistance

moval,[si]

calltran

calldisp1

jzlll

mon1:

movsi,offsetmoney

movax,[si]

subah,ah;清走高位

calldisp1

jzlll

mon2:

movsi,offsetmoney

movax,[si]

moval,ah

subah,ah

calldisp1

jzlll

lll:

movsi,offsetbz

mov[si],bh

pushdi

decdi

adddi,[si]

pushsi

movbl,[di];bl为要显示的数

popdi

movbh,0

movsi,offsetled;置led数码表偏移地址为SI

addsi,bx;求出对应的led数码

moval,byteptr[si]

movdx,io8255a;自8255A的口输出

outdx,al

popsi

moval,[si];使相应的数码管亮

movdx,io8255b;B口是控制数码管的使能端

outdx,al

movbh,[si]

shrbh,1

cmpbh,0

jnzlll

ret

dispendp

2、主程序主要代码

start:

calldisp;调用显示模块

movdx,io8255c;读C口状态

inal,dx

testal,10h;测试D4=1,运动/静止测试位,

jnzrun;当是的话就代表运动

jzstop;否则是静止等待

run:

testal,20h;测试D5=1,单程/双程测试位,

jnzsingle;当是的话就是单程

jzdouble;否则为双程

single:

movsi,offsetdistance

movdi,offsetDA3

cmpbyteptr[si],03h;判断distance里面的数据是否大于3

jbend1

movbl,[si];计算出位移量

subbl,3

movax,[di+bx];查表得到价钱

pushsi

movsi,offsetmoney

callsum

popsi

end1:

incbyteptr[si];由于该指令只有一个操作数,如果要使内存单元的内容加1,则程序中必须有说明该存储单元是字还是字节的符号或说明语句

calldelay

jzstart

double:

movsi,offsetdistance

movdi,offsetDA2

cmpbyteptr[si],03h

jgend2

movbl,[si];计算出位移量

subbl,3

movax,[di+bx];得到价钱

pushsi

movsi,offsetmoney

callsum

popsi

end2:

incbyteptr[si];位移+1

calldelay;延时程序

jzstart

stop:

movdx,io8255c

inal,dx

testal,30h;D6=1,时间定时位,接8253的定时输出,如果是的话就记一次时

jzstop;没有计足够时间的话,继续扫描访问

movsi,offsettimes

incbyteptr[si];时间加1

movbl,[si]

movdi,offsetDA1

movax,[bx+di-1]

pushsi

movsi,offsetmoney;将money更新

callsum

popsi

jmpstart

mainendp

3、软件调试:

1、用TD调试工具对每个子程序模块进行单步断点测试,观察各寄存器,标志寄存器的状态是否正确,重点关注跳转指令处是否跳转正确。

对中断服务子程序模块的调试重点检查断点的现场保护和现场的恢复,观察堆栈段的压栈和出栈的情况。

2、整个程序连接起来,系统调试,对照流程图,确定各子程序的相互调用正确,条件转移正确,数码管的显示是否正确,一切正常后,对系统的功能逐一验证,检测每一项功能是否能正确执行。

五.分析与总结

这次实验完成的是出租车计价器的设计,调试工作,完成了大部分基础功能的要求。

通过这个我掌握了8255,8253以及数码管的具体使用方法,加深了对他们的理解。

因为时间比较仓促,在当时的验收中,进行了对价格、里程、等待时间的计数,各种费用也能很好地显示出来,但是并没有很好地显示出累加后的费用。

如果改善累加的算法,会使整个设计更加合理,更加完整。

若加上直流电机的使用,会使整个设计更加贴近于真实的模拟。

这些都需要进一步的改进。

在整个设计的过程中,困难总是会有的,最大的困难就是数码管的使用,由于在先前的实验中,没用实实在在的对数码管进行编程。

由于调试数码管花了大量的时间,因此到后来才发现程序中的算法存在漏洞,但是到最后还是克服了困难。

这次实验给我最大的收获就是,将原来有些枯燥的基本实验实例化了,实际设计了利用微机系统的一些应用。

了解到微机,乃至以后单片机的一些设计和应用的方法。

当然,如果时间更加充裕的话,我相信我的设计还会做的更加完善。

 

参考书目:

[1]东南大学《微机系统与接口》课程组,微机实验及课程设计教程(试用版2.0),2009年2月

[2]杨素行等编著,《微型计算机系统原理及应用(第2版)》,北京,清华大学出版社,2004年

附录:

源代码

datasegment

ioportequ0c800h-0280h

io8255aequioport+288h;将A口设为输出

io8255bequioport+289h;将B口设为输入

io8255cequioport+28ah;将C口设为输入,判断位

io8255dequioport+28bh

io8253aequioport+280h;计数器通道0地址

io8253bequioport+281h;计数器通道1地址

io8253cequioport+283h;8253控制寄存器地址

DA1DW0002h,0004h,0006h,0008h,0010h,0012h,0014h,0016h,0018h,0020h,0022h,0024h,0026h,0028h,0030h,0032h,0034h,0036h,0038h,0040h,0042h,0044h,0046h,0048h,0050h,0052h,0054h,0056h,0058h,0060h,0062h,0064h,0066h,0068h,0070h,0072h,0074h,0076h,0078h,0080h,0082h,0084h,0086h,0088h,0090h,0092h,0094h,0096h,0098h;等待费用

DA2DW0080h,0092h,0104h,0116h,0128h,0140h,0152h,0164h,0176h,0188h,0200h,0212h,0224h,0236h,0248h,0260h,0272h,0284h,0296h,0308h,0320h,0332h,0344h,0356h,0368h,0380h,0392h,0404h,0416h,0428h,0440h,0452h,0464h,0476h,0488h,0500h,0512h,0524h,0536h,0548h,0560h,0572h,0584h,0596h,0608h,0620h,0632h,0644h,0656h,0668h,0680h,0692h,0704h,0716h,0728h,0740h,0752h,0764h,0776h,0788h,0800h,0812h,0824h,0836h,0848h,0860h,0872h,0884h,0896h,0908h,0920h,0932h,0944h,0956h,0968h,0980h,0992h

;双程费用

DA3DW0080h,0104h,0128h,0152h,0176h,0200h,0224h,0248h,0272h,0296h,0320h,0344h,0368h,0392h,0416h,0440h,0464h,0488h,0512h,0536h,0560h,0584h,0608h,0632h,0656h,0680h,0704h,0728h,0752h,0776h,0800h,0824h,0848h,0872h,0896h,0920h,0944h,0968h,0992h

;单程费用

distancedb0;存放里程数

moneydw0080h;存放费用,起步价是8元

timesdb0;存放时间

leddb3fh,06h,5bh,4fh,66h,6dh,7dh,07h,7fh,6fh;段码

buffer1db0,0;存放要显示的十位和个位

bzdw?

;位码

dataends

codesegment

assumecs:

codeds:

data

mainprocfar

;/*******************************************************************************************************/

;计时模块,分频计时1分钟

moval,00110101b;控制字:

选择通道0,先读/写低字节,后高字节,方式2,BCD计数

movdx,io8253c;指向控制口

outdx,al;送控制字

moval,00h;计数值低字节

movdx,io8253a;指向计数器0端口

outdx,al;先写入低字节

moval,00h;计数值高字节

outdx,al;后写入高字节

moval,01111001b;控制字:

选择通道1,先读/写低字节,后高字节,方式4,BCD计数

movdx,io8253c;指向控制口

outdx,al;送控制字

moval,00h;计数值低字节

movdx,io8253b;指向计数器0端口

outdx,al;先写入低字节

moval,60h;计数值高字节

outdx,al;后写入高字节

movdx,io8255d;8255初始化,A口输出,B、C口输入

moval,10001011b

outdx,al

;/******************************************************************************************************/

start:

calldisp;调用显示模块

movdx,io8255c;读C口状态

inal,dx

testal,10h;测试D4=1,运动/静止测试位,

jnzrun;当是的话就代表运动

jzstop;否则是静止等待

run:

testal,20h;测试D5=1,单程/双程测试位,

jnzsingle;当是的话就是单程

jzdouble;否则为双程

single:

movsi,offsetdistance

movdi,offsetDA3

cmpbyteptr[si],03h;判断distance里面的数据是否大于3

jbend1

movbl,[si];计算出位移量

subbl,3

movax,[di+bx];查表得到价钱

pushsi

movsi,offsetmoney

callsum

popsi

end1:

incbyteptr[si];由于该指令只有一个操作数,如果要使内存单元的内容加1,则程序中必须有说明该存储单元是字还是字节的符号或说明语句

calldelay

jzstart

double:

movsi,offsetdistance

movdi,offsetDA2

cmpbyteptr[si],03h

jgend2

movbl,[si];计算出位移量

subbl,3

movax,[di+bx];得到价钱

pushsi

movsi,offsetmoney

callsum

popsi

end2:

incbyteptr[si];位移+1

calldelay;延时程序

jzstart

stop:

movdx,io8255c

inal,dx

testal,30h;D6=1,时间定时位,接8253的定时输出,如果是的话就记一次时

jzstop;没有计足够时间的话,继续扫描访问

movsi,offsettimes

incbyteptr[si];时间加1

movbl,[si]

movdi,offsetDA1

movax,[bx+di-1]

pushsi

movsi,offsetmoney;将money更新

callsum

popsi

jmpstart

mainendp

dispprocnear

movdi,offsetbuffer1

loop2:

movbh,02

test_it:

movdx,io8255d;然后利用C口判断究竟给buffer1赋什么值,赋值子程序

inal,dx

testal,01h;如果C口读到D0=1,则跳转到时间显示模块

jnztime

testal,02h;如果C口读到D1=1,则跳转到历程显示模块

jnzdis

testal,04h;如果C口读到D2=1,则跳转到费用1(个位十位)显示模块

jnzmon1

testal,08h;如果C口读到D3=1,则跳转到费用2(千位百位)显示模块

jnzmon2

time:

movsi,offsettimes

moval,[si]

calltran;数值转换,将16进制数转换成压缩型BCD码

calldisp1

jzlll

dis:

movsi,offsetdistance

moval,[si]

calltran

calldisp1

jzlll

mon1:

movsi,offsetmoney

movax,[si]

subah,ah;清走高位

calldisp1

jzlll

mon2:

movsi,offsetmoney

movax,[si]

moval,ah

subah,ah

calldisp1

jzlll

lll:

movsi,offsetbz

mov[si],bh

pushdi

decdi

adddi,[si]

pushsi

movbl,[di];bl为要显示的数

popdi

movbh,0

movsi,offsetled;置led数码表偏移地址为SI

addsi,bx;求出对应的led数码

moval,byteptr[si]

movdx,io8255a;自8255A的口输出

outdx,al

popsi

moval,[si];使相应的数码管亮

movdx,io8255b;B口是控制数码管的使能端

outdx,al

movbh,[si]

shrbh,1

cmpbh,0

jnzlll

ret

dispendp

;/*************************************************************/

;把相应存储里程、时间和价钱的单元放到buffer中去

disp1procnear

pushsi

pushbx

movbx,offsetbuffer1

movah,al

andal,01h;清掉高4位

mov[bx],al

moval,ah

moval,10h;清掉低4位

movcl,04h

shral,cl;右移4位,把十位放进去

mov[bx+1],al

popbx

popsi

ret

disp1endp

;/*************************************************************/

;/***********************************************************/

;累加金钱程序

sumprocnear

pushbx

movbx,[si]

adcax,bx

daa

movbl,al

moval,ah

addal,0

daa

movbh,al

mov[si],bx

popbx

ret

sumendp

;/*******************************

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 解决方案 > 学习计划

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1