《课程设计论文基于单片机出租车计价器.doc》由会员分享,可在线阅读,更多相关《课程设计论文基于单片机出租车计价器.doc(28页珍藏版)》请在三一办公上搜索。
1、单片机课程设计 出租车计价器目 录前 言1第一章方案设计21.1 功能要求21.2 系统工作原理及其组成2第二章 硬件设计42.1 单片机最小系统单元42.2 光电开关单元52.3 键盘调整单元72.4 7279键盘、显示接口8第三章 软件设计103.1 系统主程序103.2 中断程序123.3 计算程序123.4 显示程序13第四章 系统测试154.1 调试与测试154.2 里程计价测试15第五章 总结17参考文献18附录A:系统原理图19附录B:源程序及注释20前 言随着生活水平的提高,人们已不再满足于衣食住的享受,出行的舒适已受到越来越多人的关注。于是,出租车行业以低价高质的服务给人们带
2、来了出行的享受。但是总存在着买纠纷困扰着行业的发展。而在出租车行业中解决这一矛盾的最好方法就是改良计价器。用更加精良的计价器来为乘客提供更加方便快捷的服务。我国在70年代开始出现出租车,但那时的计费系统大都是国外进口不但不够准确,价格还十分昂。随着改革开放益深入,出租车行业的发展势头已十分突出,国内各机械厂家纷纷推出国产计价器。出租车计价器的功能从刚开始的只显示路程(需要司机自己定价,计算后四舍五入),到能够自主计费,以及现在的能够打发票和语音提示、按时间自主变动单价等功能。随着城市旅游业的发展,出租车行业已成为城市的窗口,象征着一个城市的文明程度。现在各大中城市出租车行业都已普及自动计价器,
3、所以计价器技术的发展已成定局。而部分小城市尚未普及,但随着城市建设益加快,象征着城市面貌的出租车行业也将加速发展,计价器的普及也是毫无疑问的,所以未来汽车计价器的市场还是十分有潜力的。凡乘过出租车的人都知道,只要汽车开动,随着行驶里程的增加,就会看到汽车前面的计价器里程数字显示的读数从零逐渐增大,而当行驶到某一值时(如5KM)计费数字显示开始从起步价(如10元)增加。当出租车到达某地需要在那里等候时,司机只要按一下“计时”键,每等候一定时间,计费显示就增加一个该收的等候费用。汽车继续行驶时,停止计算等候费,继续增加里程计费。到达目的地,便可按显示的数字收费。汽车计价器是乘客与司机双方的交易准则
4、,它是出租车行业发展的重要标志,是出租车中最重要的工具。它关系着交易双方的利益。具有良好性能的计价器无论是对广大出租车司机朋友还是乘客来说都是很必要的。因此,汽车计价器的研究也是十分有一个应用价值的。采用模拟电路和数字电路设计的计价器整体电路的规模较大,用到的器件多,造成故障率高,难调试,对于模式的切换需要用到机械开关,机械开关时间久了会造成接触不良,功能不易实现。为此我们采用了单片机进行设计,相对来说功能强大,用较少的硬件和适当的软件相互配合可以很容易的实现设计要求,且灵活性强,可以通过软件编程来完成更多的附加功能。第一章方案设计1.1功能要求1. 用前4位数码管实时显示里程数(Z),单位为
5、公里,最后一位为小数位;用后4位数码管时时显示金额数(J),单位为元,最后一位为小数位。2. 规定出租车单程价格为2元/公里,往返则价格为1.5元/公里;单程/往返分别由“单程” 按键和“往返” 按键设定。3. 车速5公里/小时的时间累积为总等待时间T(分钟),每5分钟等待时间相当于里程数增加1公里。4. 起步公里数为3公里,价格为6元;若实际运行大于3公里, 按“设计任务2”计算价格。5. 必须充分利用比赛指定的硬件平台上的资源进行设计。6. 用单片机控制电机转动,并用光电传感器检测转盘转动模拟车速,车速与转盘转速成正比。转盘转速为5转/秒对应车速为5公里/小时,转盘转速为50转/秒对应车速
6、为50公里/小时,依此类推。7. 要求公里数检测误差不超过10。8. 到达目的地后,按“暂停” 键,计价器可暂停计价。9. 按“清除” 键,计价器能将记录数据(里程、等待时间与价格等)自动清0。10.按“查询”键,能自动显示总等待时间T,再按下该键回到显示里程数、金额状态。1.2系统工作原理及其组成出租车计价是根据车所行驶的路程以及乘客乘车的方式综合决定的。出租车行驶总路程可以通过车轮的周长乘车轮旋转圈数得到。即可计算得到车轮旋转几周出租车能行驶一公里的路程。因此,使用槽型光耦的目的就是方便地计量车轮旋转的圈数。可在车轮转轴涂上白色条纹,其余部分涂成黑色,发光管照射转轴。当转轴转动时,反光与不
7、反光交替出现,所以槽型光耦间断地接收光的反射信号,输出电脉冲。再经过整形电路,输出标准TTL信号。输出的脉冲信号被接入到STC89C52单片机系统中,通过计算接收到的脉冲个数,计算出当前所行驶的路程。同时,根据不同的收费标准,选择相应的起步价、单价等收费标准进行计算。HD 7279管理键盘和数码显示,通过键盘能够实现启动、暂停、停止计价器、切换显示当前的行驶里程和需支付的车费。出租车计价器用于记录里程、等待时间、是否往返、起步公里数与价格的关系,它能有效地避免司机与乘客间的矛盾,保障双方的利益。模拟出租车计价器能根据总里程数、总等待时间长短、是否往返、起步公里数的情况作出相应报价等。当然实际的
8、出租车计价器还具有能打印出车票等功能。总体模块如图1.2所示。 图1.2 电路的组成部分第二章 硬件设计2.1 单片机最小系统单元主控机系统采用了Atmel 公司生产的 STC89C52单片机,它含有256 字节数据存储器,内置8K 的电可擦除FLASH ROM,可重复编程,大小满足主控机软件系统设计,所以不必再扩展程序存储器。复位电路和晶振电路是STC89C52 工作所需的最简外围电路。单片机最小系统电路图如图2.1所示。图2.1 单片机最小系统图STC89C52 的复位端是一个史密特触发输入,高电平有效。RST端若由低电平上升到高电平并持续2个周期,系统将实现一次复位操作。在复位电路中,按
9、一下复位开关就使在RST端出现一段时间的高电平,外接11.0592M 晶振和两个30pF 电容组成系统的内部时钟电路。2.2 光电开关单元传耦合器以光为媒介输电信号。它对输入、输出电信号有良好的隔离作用,所以,它在各种电路中得到广泛的应用。目前它已成为种类最多、用途最广的光电器件之一。光耦合器一般由三部分组成:光的发射、光的接收及信号放大。输入的电信号驱动发光二极管(LED),使之发出一定波长的光,被光探测器接收而产生光电流,再经过进一步放大后输出。这就完成了电光电的转换,从而起到输入、输出、隔离的作用。由于光耦合器输入输出间互相隔离,电信号传输具有单向性等特点,因而具有良好的电绝缘能力和抗干
10、扰能力。又由于光耦合器的输入端属于电流型工作的低阻元件,因而具有很强的共模抑制能力。所以,它在长线传输信息中作为终端隔离元件可以大大提高信噪比。在计算机数字通信及实时控制中作为信号隔离的接口器件,可以大大增加计算机工作的可靠性。而槽型光耦为中断槽隙透视式光电传感器。槽型光耦的特点:信号单向传输,输入端与输出端完全实现了电气隔离,输出信号对输入端无影响,抗干扰能力强,工作稳定,无触点,使用寿命长,传输效率高。光耦合器是70年代发展起来产新型器件,现已广泛用于电气绝缘、电平转换、级间耦合、驱动电路、开关电路、斩波器、多谐振荡器、信号隔离、级间隔离 、脉冲放大电路、数字仪表、远距离信号传输、脉冲放大
11、、固态继电器(SSR)、仪器仪表、通信设备及微机接口中。在单片开关电源中,利用线性光耦合器可构成光耦反馈电路,通过调节控制端电流来改变占空比,达到精密稳压目的。槽型光耦的工作原理:槽隙两边分别装有红外发射器和接收器。当槽内无物体时,红外发射管的光直接照在硅光敏三极管的窗口上,从而产生大的电流输出;当有物体经过槽隙时,切断了光路,阻挡了信号的传输,这时光敏三极管无输出,这样可以辨别物体的有无。槽型光耦的应用:(1) 在逻辑电路上的应用 光电耦合器可以构成各种逻辑电路,由于光电耦合器的抗干扰性能和隔离性能比晶体管好,因此,由它构成的逻辑电路更可靠。 (2) 作为固体开关应用 在开关电路中,往往要求
12、控制电路和开关之间要有很好的电隔离,对于一般的电子开关来说是很难做到的,但用光电耦合器却很容易实现。 (3) 在触发电路上的应用 将光电耦合器用于双稳态输出电路,由于可以把发光二极管分别串入两管发射极回路,可有效地解决输出与负载隔离地问题。 (4) 在脉冲放大电路中的应用 光电耦合器应用于数字电路,可以将脉冲信号进行放大。 (5) 在线性电路上的应用 线性光电耦合器应用于线性电路中,具有较高地线性度以及优良地电隔离性能。 (6) 特殊场合的应用 光电耦合器还可应用于高压控制,取代变压器,代替触点继电器以及用于A/D电路等多种场合。光电脉冲的转换电路如图2.2所示:图2.2光电脉冲的转换电路槽型
13、光耦用VCC=5V电源(如图2-2),可以安装在出租车车轮处。当出租车在行进过程中,则车轮就会不断对它遮挡,从而产生一系列脉冲。由于这些脉冲可能会被干扰,或者电平不稳定,因此就需要增加一个三级管(Q1)对信号进行放大。而74LS14是作为反相器的功能来使用,可以使OUT口输出的脉冲符合TTL电平,直接可输入到STC89C52的INT0口。计算:由于槽型光耦中的二极管的导通电压为0.7V,流过的电流为10mA,而电压源为5V电压,故R1两端电压为U=4.3V,流过的电流为I=10mA,因此R1=U/I=4.3V/10mA=430500。而上拉电阻R2是用来限流,故R210K,故R2=10K。设计
14、中以槽型光耦作为传感器元件,并且在实现阶段用函数信号发生器模拟光电传感器实现计程脉冲的形成。 2.3 键盘调整单元当单价等信息需要进行修改时,就要用到键盘进行修改。由于调节信息不多,故采用4个独立键盘即可,分别实现显示金额和公里数、 清零、暂停、单程和往返功能等作用。键盘采用4*4矩阵按键,接在STC89C52的P3口,当有键按下时,相对应的接口被置0。矩阵键盘又称为行列式键盘,它是用4条I/O线作为行线,4条I/O线作为列线组成的键盘。在行线和列线的每一个交叉点上,设置一个按键。电路原理图如图2.3所示,行线接P3.0P3.3,列线接P3.4P3.7。S8:按1次,显示金额和公里数;按2次,
15、进入调整中途等待计价。S9:对上一次的计费进行清零,为下次载客准备。S10:停止计价,方便客户查看金额。S11:实现单程和往返单价的切换。图2.3 键盘调整单元接线图2.4 7279键盘、显示接口采用HD7279芯片构成键盘显示电路,HD7279是一片具串行接口的,可同时驱动8位共阴式数码的智能显示驱动芯片,该芯片同时还可以连接多达64键的键盘矩阵,单片即可完成LED显示、键盘接口的全部功能。DIG0DIG7和SASG键盘的列线和行线端口,用来完成对键盘的监视,译码和键值的识别。DIG0DIG7为8个LED管的位驱动输出端,SASG分别为LED数码管的A段G段的输出端,DP为小数点的驱动输出端
16、。HD7279与单片机仅需4跟接口线,其中的CS为片选信号,当单片机访问HD7279即读键号或写指令时,应将片选端置为低电平,低电平有效。CLK为数据串行传送的同步时钟输入端,时钟的上升沿表示数据有效。DATA为串行数据端,当向HD7279发送数据时,DATA为输入端;当HD7279输出键盘代码时,DATA为输出端。KEY为按键信号输出端,在无键按下时为高电平;而有键按下时此引脚变为低电平并且一直保持到键释放为止。在64阵列键盘中每个键的键码是用十六进制表示的,可用读键盘数据指令读出,其范围是00H3FH。HD7279需要一外接的RC震荡电路以供系统工作,其典型值R=1.5k,C=15pF。R
17、ESET为复位端。该端口由低电平变成高电平并保持25ms即复位结束。HD7279A片内具有驱动电路,它可以直接驱动LED数码管,使外围电路变得简单可靠。HD7279键盘、显示接口电路如图2-4:图2.4 7279键盘显示接口电路第三章 软件设计软件是单片机系统的灵魂,根据设计的要求,在本系统中主要有主程序、中断服务程序和键盘显示子程序、计算子程序等。在主程序中主要完成了寄存器的初始化部分以及对键盘和显示的控制。而现在应用更广泛的是单片机C语言,因其简单明了,故此次课程设计采用单片机C语言编程。3.1系统主程序 在主程序模块中,需要完成对各参量和接口的初始化、出租车起价和单价的初始化以及中断、计
18、算、循环等工作。另外,在主程序模块中还需要设置启动/清除标志寄存器、里程寄存器和价格寄存器,并对它们进行初始化。然后,主程序将根据各标志寄存器的内容,分别完成启动、清除、计程和计价等不同的操作。 当汽车运行起来时,就启动计价,根据里程寄存器中的内容计算和判断行驶里程是否已超过起步价公里数。若已超过,则根据里程值、每公里的单价数和起步价数来计算出当前的总金额,并将结果存于总金额寄存器中;中途等待时,无脉冲输入,不产生中断,当时间超过等待设定值时,开始进行计时,并把等待价格加到总金额里,然后将总金额、里程和单价、往返价格送数码管显示出来。程序流程如图3.1所示。、各单元初始化及7279初始化T0初
19、始化(计数方式 中断允许)调键扫描程序是否有键按下开始求取键号并保存启动键8?启动T0 开始计价切换键9?切换显示金额里程暂停键10?停止计费等待时间键8?复位键11?单程 往返价格切换 清零返回 图3.1 主程序流程图3.2 中断程序 每当光电传感器输出一个低电平信号就使单片机中断一次,当里程计数器对里程脉冲计满3600次时,进入里程计数中断服务程序中,里程变量加一。主函数中总金额也相应地变化。在中途等待中断程序中,每1ms产生一次中断,将由当前里程计算出速度值送入某个缓存变量,每5分钟将缓存变量中的值和当前速度值比较,当汽车小于设定的车速,光电传感器5分钟输出信号,当前速度值小于缓存变量内
20、的值,则进入等待计时,每5分钟记一次价格。如图3.2中断开始中断初始化是否到60次脉冲计数测量速度返回 图3.2 中断服务程序3.3 计算程序计算程序根据里程数分别进入不同的计算公式。如果里程大于3公里,则执行公式:总金额=起步价+(里程-3)*单价+等待时间*等待单价;否则,执行公式:总金额=起步价+等待时间*等待单价;程序框图如3.3所示。里程3?总金额=起步价总金额+=(里程-3)*单价调用计算程序总金额+=等待时间*等待单价返回总金额=起步价总金额+=等待时间*等待单价图3.3 计算程序框图3.4 显示程序程序利用定时器每1ms产生一次中断,相应变量置位,点亮一个数码管,显示一位数据,
21、利用主函数内的循环,实现动态扫描显示,同时根据数码管余辉和人眼暂留现象,即可实现显示。 0x1c,0x1d,0x1e,0x1f,0x14,0x15,0x16,0x17, 0x0c,0x0d,0x0e,0x0f,0x04,0x05,0x06,0x07; /实际电路当中所测得键值编码s0-s15开始接收里程数,价格显示数据Flag2是否为真转化为字型码输出显示接收等待时间车速显示数据返回 图3.4 键盘显示子程序第四章 系统测试4.1调试与测试采用KeilC51编译器进行源程序编译及仿真调试,同时进行硬件电路板的设计制作。硬件电路制作完毕,用万用表检测有无短路开路等现象,确定硬件电路没有问题后,用
22、仿真头与硬件电路相连,运行程序进行调试。若调试不成功,则可再单独调试程序和硬件电路。程序用软件仿真运行,硬件电路再次检查有无焊错,或者元件与插座接触不良等方面问题;确认均无问题后,再次把软件和硬件联机调试,直至功能正常。把程序烧录进单片机STC89C52结束调试。4.2 里程计价测试 由于实验条件的限制,我们采用光电传感器产生外部中断,设定中断间隔为10ms,假定3600个脉冲为1公里,则此时车速为1km/h=5圈/S.整个系统以此为基础,通过计费程序完成中金额的计算。表4.1的测试条件是:假设单程的单价是1.5元,起步价为8元(包含3公里),分别不公里程测试得数据如表: 表4.1 实际金额和
23、里程数4km6km7km9km 总 金额理论 6.5元 9.5元11元 14元实际 6.5元9.5元11元14元行驶里程理论4km6km7km9km实际4km6km7km9km表4.2的测试条件是:假设在单程运行中的单价1.5元的情况下行驶了10km,进行中途等待,分别等待不同的时间(5分钟为一个单位计费1元),起步价为8元(包含3km)。表4.2 总金额对比5min10min15min20min总金额理论 16.5元17.5元18.5元19.5元实际16.5元17.5元18.5元19.5元 第五章 总结为了使我们设计的系统更具人性化,我们将电源开关都引到盒外,是用了手动开关按键,使用起来非常
24、方便。通常在不同的方式,不同的情况下都会有不同的收费标准;单程、白天和中途等待,考虑后首选用开关来实现这些切换功能,简单方便,同时显示器会显示相应的指示。最大的方便了司机的计费控制。并且能根据市场经济的变化而发生相应的跳动计价。但是设计和调试的过程中,也发现了一些问题,譬如计价的金额数有限,实际的里程可能会很远,会超出实际的显示范围;计价过程出现突然断电时如何处理这些问题,因此对此方案还可以进行进一步改进,如:实现白天、晚上计费自动切换和具有记忆功能,这样可以保证了乘客和司机的利益。计价器的设计不够人性化,比如加上语音的提示功能。可能会更有生命力。小组在动手的过程中产生一个想法,如果计价器兼具
25、有防作弊功能可能会更让乘客放心乘坐出租车,并得到广泛的应用。参考文献1 谭浩强著. C程序设计M. 北京:清华大学出版社, 20052 张友德、赵志英、涂时亮著.单片微型机原理、应用与实验M. 上海:复旦大学出版社, 2006.103 吴戈、李玉峰编著.案例学单片机C语言开发M.北京: 人民邮电出版社,2008.104 孙余凯.传感器应用电路300例M. 北京:电子工业出版社, 2008.5 田立. 51单片机C语言程序设计快速入门M. 北京:人民邮电出版社, 20076 AT89C52概述EB/OL:7 Chirs J.Georgopoulos.Interface Fundamentals
26、In MicroprocessorControlled SystemM.D.Reidel Publishing Company,1985附录A:系统原理图附录B:源程序及注释#include #define uchar unsigned char#define uint unsigned int/*7279指令*/#define com_read 0x15 /读键盘数据指令/*变量及I/O口定义 */ sbit cs= P10; /cs 连接于 P1.0,低电平有效sbit clk=P11; /clk 连接于 P1.1sbit key=P13; /dat 连接于 P1.2sbit dat=P1
27、2; /key 连接于 P1.3,低电平有效 /*函数原型声明 */void write7279(uchar,uchar); /写入到HD7279uchar read7279(uchar); /从HD7279读出 void send_byte(uchar); /发送一个字节uchar receive_byte(void); /接收一个字节void short_delay(void); /延时约8usvoid long_delay(void); /延时约50usvoid delay_10ms(uchar times); /延时约times*10msvoid delay_1ms(uchar tim
28、es) ; /延时约times*1ms void Init_date();uchar qianwei,baiwei,shiwei,gewei;uint tt,aa,aaa,wait,dengdai,gongli,jiage,jg;bit flag0,flag1,flag2,flag3;uchar led=0x1c,0x1d,0x1e,0x1f,0x14,0x15,0x16,0x17, 0x0c,0x0d,0x0e,0x0f,0x04,0x05,0x06,0x07; /键值编码s0-s15 /*发送字节函数 发送的字节为out_byte*/void send_byte(uchar out_byt
29、e) uchar i; cs=0; long_delay(); for(i=0;i8;i+) if(out_byte&0x80) dat=1; else dat=0; clk=1; short_delay(); clk=0; short_delay(); out_byte=out_byte*2; /左移一位 dat=0; /*接收字节函数 接收的字节in_byte*/uchar receive_byte(void) uchar i,in_byte; dat=1; long_delay(); for(i=0;i8;i+) clk=1; short_delay(); in_byte=in_byte
30、*2; if(dat) in_byte=in_byte|0x01; clk=0; short_delay(); dat=0; return(in_byte); /*发送带数据指令函数*/void write7279(uchar commond,uchar date) send_byte(commond); send_byte(date); /*读指令函数*/uchar read7279(uchar commond) send_byte(commond); return(receive_byte(); /*短延时函数1*/void short_delay(void) /延时约8us uchar
31、i; for(i=0;i2;i+); /*短延时函数2*/void long_delay(void) /延时约50us uchar i; for(i=0;i12;i+); void zting()/停止子程序 flag1=!flag1;if(flag1) EX0=0; /关闭中断 定时器TR0=0;elseEX0=1;TR0=1; uchar read_key_code(void) /读键值 uchar i_code;if(!key)i_code=read7279(0x15);while(!key); /消除键盘抖动 return i_code; /读键盘值 else return 0xff;
32、 /无键盘按下uchar read_key_number(void) /读键盘号 uchar l_o;uchar i;l_o=read_key_code();if(l_o!=0xff) /判断是否有键盘按下for(i=0;i!=l_o;i+);return i;else return 0xff;void keyscan()uchar k_p;k_p=read_key_number(); /读键值号 选择相应的操作 switch(k_p)case 12: flag0=!flag0;break; /显示金额 公里 等待时间T 脉冲数 case 13: Init_date();break; /数据初
33、始化函数case 14: zting();break; /暂停 case 15: flag2=1;break; /单程 case 11: flag2=0;break; /往返 default :break;void jisuan()/计算数据处理 if(0=aaa180) gongli=aaa/6+dengdai/3000;jiage=jg*(gongli-30)/10+60;wait=dengdai/100;void fenli(uint temp,uchar dd,uchar ee,uchar ff,uchar gg) /数据的分离处理 if(temp=9999) temp=9999;qi
34、anwei=temp/1000;baiwei=temp/100%10;shiwei=temp%100/10|0x80;gewei=temp%10; write7279(dd,qianwei);write7279(ee,baiwei);write7279(ff,shiwei);write7279(gg,gewei);void display() /7279显示程序if(flag0)write7279(0x98,0xff);fenli(wait,0x87,0x86,0x85,0x84); fenli(aaa,0x83,0x82,0x81,0x80); /显示脉冲数 elsewrite7279(0x
35、98,0xff);fenli(gongli,0x87,0x86,0x85,0x84);fenli(jiage,0x83,0x82,0x81,0x80);void Init_date() /数据初始化 aaa=0;tt=0;wait=0;dengdai=0;gongli=0;jiage=0;flag0=0;flag1=0;flag2=0; flag3=0; void init() /定时器初始化 TMOD=0x01;TH0=(65536-10000)/256;TL0=(65536-10000)%256;IE=0x83;IT0=1; /外部边沿触发方式 TR0=1;void main()/主程序
36、Init_date(); /调用数据初始数据init(); /定时器初始化send_byte(0xa4);/初始化7279 while(1)keyscan(); /键盘扫描jisuan(); /数据处理display(); /显示 /*中断*/void zd() interrupt 0 /中断0aa+;if(flag3)aaa+; /进入中途等待计价 /*定时器*/void time0() interrupt 1 /定时0TH0=(65536-10000)/256; /10msTL0=(65536-10000)%256;tt+;if(tt=100) /1s采样tt=0;aa=aa/5; /速度(n*圈/s)if(aa=5) flag3=0;else flag3=1;aa=0;if(!flag3) dengdai+;27