目 录
一. 课程设计目的与要求…………………………………………………………………..1 二.方案论证与原理设计……………………………………………………………………1 三.详细设计…………………………………………………………………………………2 四.方案实现与测试…………………………………………………………………………4 五.分析与总结………………………………………………………………………………5
1、课程设计目的
(1)巩固已学的微机原理与接口的基本知识; (2)锻炼自己分析问题和解决问题的能力;
(3)为通过本课程设计让学生更好地将所学知识进行应用,更深刻地理解微机原理与接口课程的知识。 2、基本要求
设计一个出租车自动计价器,计费包括起步价、行车里程计费、等待时间计费三部分,用三只数码管 显示总金额,最大值为99.9 元,起步价8.0 元,3 公里之内按起步价计费,超过3 公里,往返双程可设每1 公里1.2 元,单程每公里2.4 元,等待时间每分钟0.2 元。用两位数码管显示总里程数,最大值99km, 用两位数码管显示等待时间(分钟),最大值99 分钟。用直流电机模拟出租车行驶,里程数与脉冲个数成 正比,每1km 脉冲数100 个(可设定),低于每小时5 公里时作为等待状态。
(1)假设有计数比较器测定停车与行车状态,转换成开关信号。开关输入行车状态,并用LED 灯显示;同时有空车信号,可用于启动计价并用LED 灯显示; (2)记录里程数,等待时间,计算总金额,并实时显示; (3)模拟刹车和启动动作,动作后立即停车/行车; (4)简单的标定和检错功能。 3、进一步设计要求
(1)打印输出功能,在屏幕上打印上下车时间、里程、价格; (2)保存最近5次数据,可选择打印在屏幕上以便检查; (3)有语音提示功能。
二.方案论证与原理设计
为实现课程设计中的要求,即完成一个出租车自动计价器,可以将出租车自动计价器系统分成5个模
块:控制模块、计程、计时模块、计费模块和显示模块。出租车自动计价器系统各模块如下图所示:
控制模块 计程模块 《微机实验及课程设计》报告 08010406 扈霁
计时模块
计费模块
其中控制模块用来输入出租车的行驶状态:启动、行车、等待、停止;计程模块记录出租车行驶的路程;即使模块记录出租车等待时间;计费模块实现出租车费用的计算;显示模块将总费用、行驶路程、等待时间在屏幕和数码管上显示。各个模块之间进行数据交换和处理,实现出租车自动计价器的功能。
三. 详细设计
1、控制模块
控制模块主要由逻辑电平控制,将8255A口设置成输入方式,逻辑电平开关连接至8255A口,K1—
—K7依次如下表示:
K1:K1=1表示出租车停止,退出系统;K1=0表示出租车处于计费状态 K2:K2=0表示单程,每公里2.4 元;K2=1表示双程,每公里1.2元 K3、K4、K5:用于选择在数码管上显示何种数据,其中当K3=1时显示当前里程数;K3=0、K4=1时显示当前的等待时间;K3=0,K4=0,K5=1时显示当前费用的高两位;K3=0,K4=0,K5=0时显示当前费用的低两位; K7:K7=1表示出租车启动开始计价;K7=0为空车信号 2、计程、计时模块
当直流电机1S输出的脉冲数大于50时,出租车处于行车状态,此时里程变量distance=distance+脉冲数/100。 当直流电机1S输出的脉冲数小于50时,出租车处于等待状态,此时等待时间变量waitTime加一。
3、计费模块
当计程模块或计时模块完成计数后,调用计费模块,计算出当前的总费用。计算公式如下:
如果是单程状态,则
8.0元 distance<=3Km
8+(distance-3)*2.4+waitTime*0.2
distance>3Km
总费用totalFee=
如果是双程状态,则
8.0元 distance<=3Km
总费用totalFee= 《微机实验及课程设计》报告 08010406 扈霁
8+(distance-3)*1.2+waitTime*0.2 distance>3Km
4、显示模块
显示模块分为两部分,第一部分是屏幕显示,在屏幕上显示里程数、等待时间和总费用,最近5次费用等等,这部分通过DOS中断将相关数据显示即可;第二部分是通过数码管显示,由于数码管只有两个,所以可以通过机械开关K3、K4、K5选择显示当前里程数、等待时间和总费用的高低位,数码管的位选由8255芯片的C口PC0和PC1控制,数码管的段选由8255芯片的B口控制。
主程序流程图如下所示: 3km以上的距离按2.4元/km收费 调用显示程序 是 开始 从8255A口读入开关状态 是 单双程选择开关PA2=1? 否 3km以上的距按1.2元/km收费 初始化程序 数值更新显示程序 数码管显示程序 是 PA1=1? 退出程序 否 1s 定时信号PA0=1? 否 系统启动 《微机实验及课程设计》报告 08010406 扈霁
否 载客信号PA7=1? 是 计价更新程序 四. 方案实现与测试
项目中使用到的芯片介绍如下: 1、8253芯片:
计数器0设置成方式3,计数器1设置成方式0,计数器0、1的计数初值均设置为1000,然后将两个计数器级联,计数器0输入1MHz的时钟信号,利用out1产生的1S的周期信号来产生1S的定时中断。
计数器2设置成方式0,将直流电机的脉冲输入到CLK2,用来计数直流电机的脉冲数。 8253连接方式如下图所示:
2、8255芯片:
8255A口设置成输入,PA1-PA7接七位拨码开关用于输入开关状态,PA0接8253的OUT1,用来检测是否有1s定时。
8255B口设置成输出,用于控制八位数码管的段选。 8255C口设置为输出方式,用于控制八位数码管的位选。 8255连接方式如下:
《微机实验及课程设计》报告 08010406 扈霁
出租车自动计价器系统具体实现时以模块为单位进行编程、测试,共分为5个模块:控制模块、计程模块、计时模块、计费模块和显示模块。其中控制模块的测试即将开关量输入至8255A口,然后在debug状态下查看PA口的值或将其以ASCII码字符的形式输出到屏幕上显示检验,并观察程序是否按照控制要求进行跳转。显示模块则可以将屏幕显示的数值和数码管显示的数值进行对比,排除错误,其中屏幕显示程序和数码管动态显示程序可以分别独立进行调试;因为显示计程模块、计数模块和计费模块是直接的算数运算,所以可以直接通过屏幕显示或数码管显示的路程、等待时间依据设定好的计算规则进行计算,验证三个模块的数据处理是否正确。
遇到的问题:
1、 调试时发现不能在软件中点击run运行,必须先点开始调试,再按F5,后来发现点击run也是可
以直接运行的,但是相当慢,调试时一般都采用后一种方法进行了。
2、 在实现数据的显示时一直只能显示16进制,显示和读书不方便,于是增加了二进制到BCD码再到
十进制的转换。
3、 直流电机脉冲检测不到,可能跟实验箱有关系,更换实验箱后得到了解决。
4、 调速过快时状态改变不及时,计费出现错误,跟软件的延时有关,经过调整后得到了一定的好转,
但是没能彻底解决这个问题。
五.分析与总结
此课程设计验收时,我完成了5个基本要求和进一步设计要求(1)、(2)。运行程序,通过机械开关控制出租车的状态, LED灯L7显示行车状态: L7灭表示空车,L7亮表示车里有人且自动计价器在计价。可以通过调节控制直流电机的电位器来切换出租车的行驶状态。在屏幕上将动态显示出当前的路程、等待时间和费用,数码管的显示数据则可以通过开关来切换。经过多次检验和验证,本项目能正确地计算出租车行驶的费用,实现了出租车自动计价器的基本功能和部分扩展功能。
《微机实验及课程设计》报告 08010406 扈霁
在这次课程设计中,先是进行了出租车自动计价器的系统设计,采用化整为零的方法将其划分为5个子模块(控制模块、计程模块、计时模块、计费模块和显示模块)来实现,参考了各种资料,当程序完成后,进行调试、排错。在此过程中,我遇到了一些困难,当遇到这些问题时我一般是先用Debug进行断点、单步调试,查找程序中的错误,若并非程序问题,再进行硬件问题地排查。比如数码管显示错误一般是程序问题,直流电机脉冲检测不到可能就是硬件问题了。在解决问题的过程中,我积极和同组同学进行探讨、交流,互相学习,确保分工明确,出现错误知道问题在谁负责的部分,遇到不理解的地方就一起查书查资料进行讨论,实在想不出来就去问老师。
我认为进行在课程设计中应注意一下几个方面:
(1) 面对一个项目应该仔细分析项目中的各种要求,然后进行系统设计,再化整为零,将其分为
几个模块,进行模块化设计,这样有利于程序的编写与调试。
(2) 可以采用流程图的来理顺程序的运行过程,当画出流程图时,程序的思路就更加清晰明了,
也方便测试的时候理清跳转的关系,有利于测试的进行。
(3) 当程序运行有错时应学会用Debug进行单步、断点调试,观察寄存器的值,观察程序是否按
照我们所设想的一步步运行,如果排除软件问题,那么再进行硬件问题的检查。
(4) 编程和测试需要耐心和细心。我们的计费程序到最后还是有一些缺陷,速度改变过快的时候
程序反应不灵敏,有一定的延时,才能判断出当前状态是等待还是行车,在编写和测试的过程中,我们改动了数次的模块还是经常出现问题,有时候修改过后反正效果更加不好了,这时候就需要我们的耐心,不能急躁。
(5) 应该积极和老师、同学进行交流,在交流过程中将会受益匪浅。 (6) 程序中注意加注释,这样便于别人理解,也便于自己查错。 (7) 注意版本信息,在代码中的提示信息显示时要写上自己的学号
(8) 要有敢于质疑和认真思考的态度,设计要求中单程2.4元/公里,双程1.2元/公里,其实非常
不符合实际,这样单程和双程岂不是总价一样了,当然我们设计时并没有多思考,仅仅是按照要求设置了参数,但是在验收时老师提出了这个问题,反映出来我们还只是为了完成要求而做课程设计,并没有对设计的题目进行认真的思考和研究。
微机实验课程到这里就接近尾声了,在这次课程设计中,除了遇到上述技术问题,还有着不少麻烦,因为实验室的实验箱有一部分不大好,有时候我们上一次已经实现了的功能,下次来换了一个实验箱就发现又实现不了了。我们的这个项目的原理可能不是最难的,不过要连的线相对比较多,一旦测试不通过要换个箱子就要把线拆下来重新接线,着实费了不少功夫。
总的说来,此次课程设计很好地锻炼了我们分析问题、解决问题的能力,让我们掌握了一般项目地设计流程,使我们学会如何对一个新项目进行分析、设计和实现的。同时也让我们对8255、8253等芯片有了更进一步地了解,将《微型计算机系统原理及应用》这门课程所学知识学以致用。
《微机实验及课程设计》报告 08010406 扈霁
参考书目:
[1] 东南大学《微机系统与接口》课程组,《微机实验及课程设计教程(试用版2.0)》,2009年 [2] 杨素行等,《微型计算机原理与应用(第2版)》,北京,清华大学出版社,2004年
附录: 附上代码
cursor macro row,clm ;***********移动光标位置到(row,clm)******************* io8255c第三口接LED灯用来表示行车等待 push ax push bx push dx mov ah,2 mov bh,0 mov dh,row mov dl,clm
int 10h pop dx pop bx pop ax endm
data segment
ioport equ 0ec00h-0280h
io8253a equ ioport+280h ;8253计数器0地址 io8253b equ ioport+281h ;8253计数器1地址 io8253c equ ioport+282h ;8253计数器2地址
io8253d equ ioport+283h ;8253控制寄存器地址 io8255a equ ioport+288h ;8255A口地址 io8255c equ ioport+28ah ;8255C口地址 io8255b equ ioport+289h ;8255B口地址 io8255d equ ioport+28bh ;8255控制寄存器地址 onekm equ 100 ;一公里对应的脉冲数 waitnum equ 50
;参考脉冲数,小于此值
即为等待
startp equ 80 ;起步价8元
price db 24 ;行车计费,2.4元/公里 waitp equ 2 ;等待计费,0.2元/分钟
str0
db
' ',0dh,0ah,'$'; 0DH,0AH,'$'中0DH和0AH分别是回车和换行的ASCII码,'$'是DOS功能调用INT 21H中9号功能要求的要显示字符串的结束标志。
str1 db '**************** Taxi
calculating fee machine **************',0dh,0ah,'$'
str6
db
'***********************************************',0dh,0ah,'$'
str2 db '********* PRICE: 2.40 yuan/km 0.2 yuan/min ***************',0dh,0ah,'$' str12 db '********* PRICE: 1.20 yuan/km 0.2 yuan/min ***************',0dh,0ah,'$'
str3 db 'TIME:0 (M) ',0dh,0ah,'$'
str4 db 'DIST:0 (KM) ',0dh,0ah,'$'
str5 db 'COST:0 (YUAN) ',0dh,0ah,'$'
str7 db 'Five cost:',0dh,0ah,'$' str11 db 'GET OFF THE TAXI end_time:00:00:00',0dh,0ah,'$' str14 db 'start_time:00:00:00',0dh,0ah,'$' pnum dw 0 ;总脉冲数 dist db 0 ;总里程 time db 0 ;等待时间 total dw 0000h ;总费用
flag db 11h xdk
db 0
feeBuffer dw 0000h,0000h,0000h,0000h,0000h
feeCount db 0
led
db
3fh,06h,5bh,4fh,66h,6dh,7dh,07h,7fh,6fh ;段码 buffer1 db 6,5h ;存放要显示的个位和十位
bz dw ? ;位码 data ends
stacks segment stack
db 100 dup(?)
stacks ends
code segment
《微机实验及课程设计》报告 08010406 扈霁
assume cs:code, ds:data, ss:stacks main proc start: mov ax,data mov ds,ax mov ax,stacks mov ss,ax mov dx,io8255a in al,dx test al,04h jz bb mov bl,55h mov flag,bl mov bl,12 ;十进制的数字,表示往返双程可以设定为1.2元/公里 mov price,bl bb: call ini ;调用初始化子程序 call disp begin1: mov di,offset buffer1 ;设di为显示缓冲区 call lll; mov dx,io8255a in al,dx test al,02h jnz exit; test al,01h ;判断是否有1秒钟定时中断信号,1为start启动 jz begin1 call begin mov bx,total mov al,bl call extendBcd mov word ptr[buffer1],ax mov dx,io8255a in al,dx test al,00001000b jz showl1 mov al,dist call extendBcd mov word ptr[buffer1],ax jmp showl3 showl1:mov dx,io8255a in al,dx test al,00010000b jz showl2 mov al,time call extendBcd mov word ptr[buffer1],ax jmp showl3 showl2: mov dx,io8255a in al,dx test al,00100000b jz showl3 mov bx,total mov al,bh call extendBcd mov word ptr[buffer1],ax showl3: mov dx,io8255a in al,dx and al,10000000b ;判断是否有1秒钟定时中断信号 jz begin1 call gains mov bl,feeCount cmp bl,9 ja aboveCount jmp belowCount aboveCount:mov bl,0 belowCount:mov ax,total mov bh,0 mov feeBuffer[bx],ax inc bl inc bl mov feeCount,bl jmp begin1 exit:call off_texi cursor 11,0 mov ah,4ch ;退出程序 int 21h main endp extendBcd proc push bx push cx mov bl,al mov cl,4 shr al,cl mov ah,al
《微机实验及课程设计》报告 08010406 扈霁
and bl,00001111b mov al,bl pop cx pop bx ret extendBcd endp lll proc push di push bx push ax push si mov bh,2 ll: mov byte ptr bz,bh;数码管显示程序 push di dec di add di, bz mov bl,[di] ;bl为要显示的数 pop di mov al,0 mov dx,io8255c ;消隐,全部关闭 out dx,al mov bh,0 mov si,offset led ;置led数码表偏移地址为SI add si,bx ;求出对应的led数码 mov al,byte ptr [si] mov dx,io8255b ;自8255B的口输出 out dx,al mov al,byte ptr bz ;使相应的数码管亮 or al,xdk ;和0进行或运算 mov dx,io8255c out dx,al mov cx,3000 delay: loop delay ;延时 mov bh,byte ptr bz shr bh,1 jnz ll pop si pop ax pop bx pop di ret lll endp gains proc ;计价更新程序 push ax push bx push cx push dx mov ax,total and ax,ax jz return2 mov dx,io8253c ;读取脉冲数 in al,dx mov bl,al mov dx,io8253a ;计数器0重新计数 mov ax,1000 out dx,al mov al,ah out dx,al mov dx,io8253b mov ax,1000 ;计数器1重新计数 out dx,al mov al,ah out dx,al mov al,0 mov dx,io8253c ;计数器2重新计数 out dx,al mov al,0ffh ;计算脉冲数 sub al,bl inc al cmp al,waitnum ;脉冲数小于参考值则为等待状态,否则为行车状态 jb wgain mov ah,00000100b mov xdk,ah mov ah,0 add pnum,ax mov ax,pnum mov bl,100 div bl ;用脉冲数除以100就是公里数 call num2bcds ;计算行驶里程数并转化为2位压缩BCD码 mov dist,al jmp newcost wgain:mov al,0 mov xdk,al
《微机实验及课程设计》报告 08010406 扈霁
mov dx,io8255c mov al,00100011b out dx,al mov al,time ;判断为等待状态,等待时间加1 call bcd2num inc al call num2bcds mov time,al jmp newcost return2:jmp return newcost:mov al,dist ;计算当前总金额 call bcd2num mov total,startp cmp al,3 jbe cost2 sub al,3 mov bl,price ;大于3公里的花费计算 mul bl add total,ax cost2: mov al,time ;加上停车费的计算 call bcd2num mov ah,0 mov bl,waitp mul bl add ax,total call num2bcdl mov total,ax call disp ;数值更新 return: pop dx pop cx pop bx pop ax ret gains endp ;*********************2位压缩BCD码转换为十进制数*************************** bcd2num proc push bx push cx mov bh,al mov cl,4 shr al,cl mov bl,10 mul bl and bh,00001111b add al,bh pop bx pop cx ret bcd2num endp comma proc push ax push dx mov ah,2 mov dl,'.' int 21h pop dx pop ax ret comma endp ;*********************************显示程序******************************* show proc call show1 cmp dl,1 jnz down call comma down: call show11 ret show endp ;****************************显示子程序1************************************* show1 proc push dx push cx push ax mov dl,al mov cl,4 shr dl,cl add dl,30h mov ah,02h int 21h pop ax pop cx pop dx ret show1 endp ;**************************显示子程序2*********************************** show11 proc
《微机实验及课程设计》报告 08010406 扈霁
push dx push ax mov dl,al and dl,00001111b add dl,30h mov ah,02h int 21h pop ax pop dx ret show11 endp ;***************************数值更新显示程序 ******************************* disp proc push ax push bx push dx push si mov dl,0 cursor 3,6 mov al,time call show mov dl,0 cursor 4,6 mov al,dist call show mov dl,0 cursor 5,6 mov bx,total mov al,bh call show mov dl,1 mov al,bl call show mov si,0 ;mov dh,1 ;lopp: mov dl,0 cursor 7,12 mov bx,feeBuffer[si] mov al,bh call show mov dl,1 mov al,bl call show ;1 inc si inc si mov dl,0 cursor 7,21 mov bx,feeBuffer[si] mov al,bh call show mov dl,1 mov al,bl call show ;2 inc si inc si mov dl,0 cursor 7,30 mov bx,feeBuffer[si] mov al,bh call show mov dl,1 mov al,bl call show ;3 inc si inc si mov dl,0 cursor 7,39 mov bx,feeBuffer[si] mov al,bh call show mov dl,1 mov al,bl call show ;4 inc si inc si mov dl,0 cursor 7,48 mov bx,feeBuffer[si] mov al,bh call show mov dl,1 mov al,bl call show ;5
《微机实验及课程设计》报告 08010406 扈霁
;loppend pop si pop dx pop bx pop ax ret disp endp ;*********************************8位二进制码转2位压缩BCD码************************** num2bcds proc push bx push cx push dx cmp al,9 jbe _out1 mov ah,0 mov bl,10 div bl cmp al,10 jae error1 mov cl,4 shl al,cl and ah,0fh add al,ah _out1: pop dx pop cx pop bx ret error1:cursor 11,0 mov si,offset str7 mov dx,si mov ah,09h int 21h mov ah,4ch int 21h num2bcds endp ;*********************************16位二进制码转4位压缩BCD码**************************** num2bcdl proc push bx push cx push dx cmp ax,9999 ja error2 cmp ax,0009h jbe _out2 mov dx,ax mov bl,100 div bl mov bh,ah call num2bcds mov bl,al mov al,bh call num2bcds mov ah,bl _out2: pop dx pop cx pop bx ret error2: cursor 11,0 mov si,offset str7 mov dx,si mov ah,09h int 21h mov ah,4ch int 21h num2bcdl endp ;*****************************************初始化程序********************************** ini proc push ax push dx push si mov bh,7 mov dx,314fh mov ax,0600h mov cx,0 int 10h ;清屏幕 cursor 0,0 mov ax,0 mov pnum,ax mov dist,al mov time,al mov total,ax ;相关存储单元内容清零 mov dx,io8255d mov al,10010000b ;置8255工作方式为A口输入,C口输出 out dx,al mov dx,offset str1 ;在屏幕上显示提示语 mov ah,09h
《微机实验及课程设计》报告 08010406 扈霁
int 21h mov dx,offset str6 ;显示学号 mov ah,09h int 21h cmp flag,55h ;判断是否执行过flag,55h jz bbb mov dx,offset str2 ;没执行过就是2.4元一公里 jmp bbbb bbb:mov dx,offset str12 ;执行过就是1.2元一公里 bbbb:mov ah,09h int 21h mov dx,offset str3 ;显示时间 mov ah,09h int 21h mov dx,offset str4 ;显示距离 mov ah,09h int 21h mov dx,offset str5 ;显示花费 mov ah,09h int 21h mov dx,offset str14 ;显示开始时间 mov ah,09h int 21h mov dx,offset str7 ;显示等待时间的花费 mov ah,09h int 21h pop si pop dx pop ax ret ini endp ;*********************************启动计费****************************************** begin proc push ax push bx push cx push dx mov ax,total and ax,ax jnz rettt ;*********************************get_start_time******************************************* mov ah,2ch ;取时间,CH为小时,CL为分,DH为秒,DL为1/100秒 int 21h mov dl,0 mov al,ch call num2bcds cursor 6,11 call show mov al,cl call num2bcds cursor 6,14 call show mov al,dh call num2bcds cursor 6,17 call show ;***************************************************************************************** cursor 11,0 mov dx,offset str0 mov ah,09 int 21h mov al,startp call num2bcds mov ah,0 mov total,ax ;置总金额为起步价 jmp ini_hard rettt: jmp rett ini_hard:mov dx,io8253d mov al,36h ;置8253计数器0为方式3计数,初值1000 out dx,al mov al,70h ;置8253计数器1为方式0计数,初值1000,计数器0与1级联计数产生1s定时 out dx,al mov al,90h ;置8253计数器2为方式0计数,只计低字节 out dx,al mov ax,1000 mov dx,io8253a out dx,al mov al,ah out dx,al mov ax,1000 mov dx,io8253b
《微机实验及课程设计》报告 08010406 扈霁
out dx,al mov al,ah out dx,al mov dx,io8253c mov al,0 out dx,al call disp rett: pop dx pop cx pop bx pop ax ret begin endp ;*********************************结束计费****************************************** off_texi proc push ax push bx push dx mov ax,total and ax,ax jz ret2 cursor 11,0 mov si,offset str11 mov dx,si mov ah,09h int 21h ;************************************get_end_time************************************* mov ah,2ch int 21h mov dl,0 mov al,ch call num2bcds cursor 11,45 call show mov al,cl call num2bcds cursor 11,48 call show mov al,dh call num2bcds cursor 11,51 call show ;*********************************************************************************** mov ax,0 mov pnum,ax ;相关内存单元清零 mov dist,al mov time,al mov total,ax ret2: pop dx pop bx pop ax ret off_texi endp code ends end start