1、微机实验及课程设计课程设计报告出租车自动计价器东南大学自动化学院微机实验及课程设计课程设计报告综合测试题六:出租车自动计价器姓 名: 刘策 学 号: 08014116 专 业: 自动化 实 验 室: 金智楼五楼 组 别: 同组人员: 设计时间: 2016年06月 1日 2016年6 月16 日评定成绩: 审阅教师: 一课程设计目的与要求.二方案论证与原理设计.三实验流程与测试结果.四实验总结.五附录.一. 课程设计目的与要求1、课程设计目的(1)总结、应用前面八个实验中积累的微机实验经验;(2)熟悉8253、8255等芯片的使用方法;(3)结合课堂中所学的汇编语言基础知识,进行系统的编程,培养
2、动手操作能力(4)锻炼了查找错误,修正错误的能力2、课程设计要求 设计一个出租车自动计价器,计费包括起步价、行车里程计费、等待时间计费三部分,用三只数码管显示总金额,最大值为99.9 元,起步价8.0 元,3 公里之内按起步价计费,超过3 公里,往返双程可设每1 公里1.2 元,单程每公里1.8 元,等待时间每分钟0.2 元。用两位数码管显示总里程数,最大值99km,用两位数码管显示等待时间(分钟),最大值99 分钟。用直流电机模拟出租车行驶,里程数与脉冲个数成正比,每1km 脉冲数100 个(可设定),低于每小时5 公里时作为等待状态。 (1)基本要求 i假设有计数比较器测定停车与行车状态,
3、转换成开关信号。开关输入行车状态,并用LED 灯显示;同时有空车信号,可用于启动计价并用LED 灯显示; ii记录里程数,等待时间,计算总金额,并实时显示; iii模拟刹车和启动动作,动作后立即停车/行车; iv简单的标定和检错功能。 (2)进一步设计要求 i打印输出功能,在屏幕上打印上下车时间、里程、价格; ii保存最近5次数据,可选择打印在屏幕上以便检查; iii有语音提示功能。二.方案论证与原理设计 整个出租车自动计价器系统是由主程序控制模块、计价模块、显示模块三部分组成。 1、主程序控制模块总控制模块的作用是控制出租车的行车状态以及控制数码管的显示内容,包括如下几点:(1)判断是否选中
4、单程或双程(2)判断出租车是否处于等待(3)判断数码管显示内容(4)判断系统是否开始行驶具体的规划如下:以8255芯片为例,将A口定义为方式0输入,A0连接8253定时器的OUT1输出,以便用来检测是否存在1s定时。后面相继的1-5分别接到逻辑电平开关K1-K5,K6接某个与门右引脚控制直流电机的开关。而K7开关接到一个LED灯上,检验判断是处于开始计价还是空车状态。开关名称K1K2K3K4K5K6K7对应口PA1PA2PA3PA4PA5与门右引脚PA7功能K=0停止状态单程K3K4K5显示功能关闭直流电机空车状态K=1计费状态双程01X时间打开直流电机开始计价1XX里程000费用低位001费
5、用高位2、计数模块计算路程、计算时间两个,通过计数模块可以获得出租车目前行驶的路程以及已经行驶的时间,该模块的数据应用到计费模块可以行驶及等待过程的总费用。其原理是根据直流电机每秒中输出的脉冲数分情况,预先设定好一个脉冲阈值(本实验用的是10),当直流电机每秒输出的脉冲数大于10时,出租车处于行车状态,此时里程=历史里程+脉冲数/100。当直流电机每秒输出的脉冲数小于10时,出租车处于等待状态,此时等待时间加1。8253 定时器功能分配如下:计数器0设置成方式3,计数器1设置成方式0,计数器0、1的计数初值均设置为1000,然后将两个计数器级联,计数器0输入1MHz的时钟信号,利用out1产生
6、的1S的周期信号来产生1S的定时中断。计数器2设置成方式0,将直流电机的脉冲输入到CLK2,用来计数直流电机的脉冲数。3、计费模块计费模块利用计数模块提供的时间以及路程等信息,通过条件等操作针对不同的情况采用不同的计费方式,最终得到总费用。计费公式如下:4、显示模块根据设计要求我们可以将显示模块主要分为屏幕显示和数码管显示两个部分。第一部分是屏幕显示,在屏幕上显示里程数、等待时间和总费用,最近5次费用等等,可以通过调用DOS中断显示数据;第二部分是通过数码管显示,由于数码管只有两个,我们组合使用K3、K4、K5选择显示当前里程数、等待时间和总费用的高低位,数码管位选和段选分别用8255芯片的C
7、口PC0和PC1、B口PB0PB7控制。而空车信号由LED灯显示,只需将K7连接LED灯上即可显示空车状态。其中8255B口设置成方式0输出,用于控制八位数码管的段选。8255C口设置为方式 0输出方式。三. 实验流程与测试结果判断单双程从8255A口读入开关开始数值显示更新数值显示更新初始化程序数码管显示NPA1=1?YNPA0=1?Y系统启动调用显示模块NPA7=1?Y计价更新模块DJK6直流电机 54分析与总结按照题目的实验要求,我一共完成了5个基本要求和提高要求的(1)、(2)两部分。通过机械开关控制出租车的状态, LED灯L7显示行车状态: L7灭表示空车,L7亮表示车里有人且自动计
8、价器在计价。可以通过调节控制直流电机的电位器来切换出租车的行驶状态。在屏幕上将动态显示出当前的路程、等待时间和费用,数码管的显示数据则可以通过开关来切换。经过多次检验和验证,本项目能正确地计算出租车行驶的费用,实现了出租车自动计价器的基本功能和部分扩展功能。在实验中我熟悉了8253、8255的操作过程和原理,了解了直流电机、数码管的使用方法,对汇编语言的书写、编辑能力有了进一步提高。事实上我的设计过程并不是一帆风顺。一开始在查找资料后我发现了一个比较简单的思路,即把汽车实时数据预先存储在数据段的字符串里面,通过8253定时得到的时间、8253获得的直流电机脉冲数目,计算出等待时间、行驶路程等重
9、要参数,间接的从预存数据中取得费用等,显示在屏幕和数码管上。由于现实行车中不会出现太长的等待时间,出租车也不可能每客都行驶数十公里,所以我觉得可行性还是相当高的。但是后来因为其中的几个问题一直得不到解决,且这些问题由很重要,所以不得不放弃原来的思路,参考去往届学长成熟的经验方法,最终比较成功的实现了各功能。老师提出了等待脉冲阈值设定的问题,原来的脉冲阈值设定为50,太高不符合现实情况,后来进行了更改,改为10。除此之外直流电机转速过快会使屏来不及更新数据,在咨询学长后在调整速度又恢复正常。在测试代码时,调试数码管相对来说比较麻烦,程序中的算法存在一点点漏洞,会对显示造成很多影响,最终我们也发现
10、数码管显示值会比屏幕显示出来的值小数个采样,通过调整代码也没有解决它。 这次实验让我对微机系统各组成部分的工作原理有了更加清晰的认识,了解了微机乃至以后单片机的一些设计和应用的方法。这是很宝贵的收获。5附录cursor macro row,clm ;*移动光标位置到(row,clm)* io8255c第三口接LED灯用来表示行车等待 push ax push bx push dx mov ah,2 ;INT10功能号为2时,置光标位置 mov bh,0 ;页号为0 mov dh,row mov dl,clm int 10h pop dx pop bx pop axendm data segme
11、nt 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 ;8
12、255控制寄存器地址 onekm equ 100 ;一公里对应的脉冲数 waitnum equ 10 ;参考脉冲数,小于此值即为等待 startp equ 80 ;起步价8元 price db 12 ;行车计费,1.2元/公里 waitp equ 2 ;等待计费,0.2元/分钟 str0 db ,0dh,0ah,$str1 db * Taxi calculating fee machine *,0dh,0ah,$str6 db *08013226*,0dh,0ah,$str2 db * PRICE: 1.80 yuan/km 0.2 yuan/min *,0dh,0ah,$str12 db *
13、 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 ;等待
14、时间 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 endsstacks segment stack db 100 dup(?)stacks endscode segment assume cs:code, ds:data, ss:stacks
15、main procstart: mov ax,data mov ds,ax mov ax,stacks mov ss,ax mov dx,io8255a in al,dx test al,04h ;0代表单程,1代表双程 jz bb mov bl,55h ;作为单程还是双程的标志,等于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;
16、;调用数码管显示程序 mov dx,io8255a in al,dx test al,02h ;0代表计费状态,1代表结束 jnz exit test al,01h ;判断是否有1秒钟定时中断信号,1为start启动 jz begin1 ;为0则重新调用数码管显示程序 call begin ;启动计费 mov bx,total mov al,bl call extendBcd ;调用二进制转换为BCD码程序,输入为八位的al,返回值为16位的ax mov word ptrbuffer1,ax ;将低位价格BCD码存入要显示的数字的内存区 mov dx,io8255a in al,dx test
17、 al,00001000b jz showl1 ;K3=0,不显示里程数 mov al,dist call extendBcd mov word ptrbuffer1,ax ;将里程数对应的BCD码存入要显示的数字的内存区 jmp showl3showl1: mov dx,io8255a in al,dx test al,00010000b jz showl2 ;K4=0,不显示等待时间 mov al,time call extendBcd mov word ptrbuffer1,ax ;将等待时间对应的BCD码存入要显示的数字的内存区 jmp showl3showl2: mov dx,io8
18、255a in al,dx test al,00100000b jz showl3 ;K5=0,不显示价格高两位 mov bx,total mov al,bh call extendBcd mov word ptrbuffer1,ax ;将高位价格BCD码存入要显示的数字的内存区showl3: mov dx,io8255a in al,dx jz begin1 ;每过一秒钟则判断一下是否停止等等 call gains ;每过一秒钟则调用一次计费模块 mov bl,feeCount cmp bl,9 ja aboveCount jmp belowCount aboveCount:mov bl,0
19、 ;五个一循环belowCount:mov ax,total mov bh,0 mov feeBufferbx,ax inc bl inc bl mov feeCount,bl jmp begin1exit:call off_texi cursor 11,0 mov ah,4ch ;退出程序 int 21hmain endp;*扩展BCD码*extendBcd proc push bx push cx mov bl,al mov cl,4 shr al,cl ;取高四位 mov ah,al and bl,00001111b mov al,bl ;取低四位 pop cx pop bx retex
20、tendBcd endp ;*数码管显示程序*lll proc push di push bx push ax push si mov bh,2ll: 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口
21、输出段码 out dx,al mov al,byte ptr bz ;使相应的数码管亮 or al,xdk mov dx,io8255c out dx,al ;自8255C口输出位码 mov cx,3000delay: loop delay ;延时 mov bh,byte ptr bz shr bh,1 jnz ll ;右移一位判断显示的高地位,若为高位,回ll继续显示低位 pop si pop ax pop bx pop di retlll endp;*计价更新程序*gains proc push ax push bx push cx push dx mov ax,total and ax,
22、ax jz return2 ;总价是0,则返回主程序 mov dx,io8253c ;读取脉冲数 in al,dx ;将直流电机的脉冲输入到CLK2,用来计数直流电机的脉冲数 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 a
23、l,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 call num2bcds ;计算行驶里程数并转化为2位压缩BCD码 mov dist,al jmp newcost ;更新总费用wgain:mov al,0 mov xdk,al mov al,time ;判断为等待状态,等待时间加1 call bcd2num ;将2位压缩BCD码转换成十进制数字 i
24、nc al call num2bcds ;再将二进制转换为压缩BCD码,方便数码管显示 mov time,al jmp newcostreturn2:jmp returnnewcost: mov al,dist ;计算当前总金额 call bcd2num ;BCD转换为10进制 mov total,startp cmp al,3 jbe cost2 ;路程小于三公里 sub al,3 mov ah,0 mov bl,price mul bl add total,ax ;总费用cost2: mov al,time ;开始等待计费 call bcd2num mov ah,0 mov bl,wait
25、p mul bl add ax,total ;ax中等待费用加上total中路程费用 call num2bcdl ;转换为4位压缩BCD格式 mov total,ax call disp ;数值更新显示程序return: pop dx pop cx pop bx pop axretgains 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 end
26、p;*小数点显示程序*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 ;显示程序用的是al寄存器 mov cl,4 shr dl,cl ;保留高四位,清除低四位 add dl,30h ;dl存的是所显示字符的ASCII码,若显示数字,则需将其数值加上30h mov ah,02h int 21h pop ax pop cx pop dx ret show1 endp;*显示子程序2* show11 proc push dx push ax mov dl,al and dl,00001111b ;
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1