出租车计价器优秀课程设计.doc
摘 要 本设计是一个基于单片机STC89C52出租车自动计费设计,附有复位电路,时钟电路,键盘电路等。复位电路是单片机初始化操作,除了正常初始化外,为摆脱困境,经过复位电路能够重新开始。时钟电路采取12MHz晶振,作为系统时钟源,含有较高正确性。在上电时字符型液晶1602显示最初起步价,里程收费,等候时间收费三种收费,经过按键能够调整起步价,里程收费,等候时间收费。经过按键模拟出租车运行,暂停,停止。在1602液晶上能够显示运行时间,运行时暂停时间,经过计算能够得出总共费用和总旅程。在这里关键是以STC89C52单片机为关键控制器,P1口接1602液晶显示模块。关键字 STC89C52;1602液晶;出租车计费器第一章 绪论1.1 出租车计价器概述中国在70年代开始出现出租车,但那时计费系统大全部是国外进口不仅不够正确,价格还十分昂贵。伴随改革开放日益深入,出租车行业发展势头已十分突出,中国各机械厂家纷纷推出国产计价器。出租车计价器功效从刚开始只显示旅程(需要司机自己定价,计算后四舍五入),到能够自主计费,和现在能够打一发票和语音提醒、按时间自主变动单价等功效。伴随城市旅游业发展,出租车行业已成为城市窗口,象征着一个城市文明程度。此次设计目标在于现在各大中城市出租车行业全部已普及自动计价器,所以计价器技术发展已成定局。而部分小城市还未普及,但伴随城市建设日益加紧,象征着城市面貌出租车行业也将加速发展,计价器普及也是毫无疑问,所以未来汽车计价器市场还是十分有潜力。1.2 单片机概述计算机系统已显著地朝巨型化、单片化、网络化三个方向发展。巨型化发展目标在于不停提升计算机运算速度和处理能力,以处理复杂系统计算和高速数据处理,比如系统仿真和模拟、实时运算和处理。单片化是把计算机系统尽可能集成在一块半导体芯片上,其目标在于计算机微型化和提升系统可靠性,这种单片计算简称单片机。单片机内部硬件结构和指令系统关键是针对自动控制应用而设计所以单片机又称微控制器MCU(Micro Controller Unit)。用它能够很轻易地将计算机嵌入到多种仪器和现场控制设备中,所以单片机又叫做嵌入式微控制器(Embedded MCU)。单片机自20世纪70年代问世以来,以其鲜明特点得到迅猛发展,已广泛应用于家用电器、智能玩具、智能仪器仪表、工业控制、航空航天等领域,经过30多年发展,性能不停提升,品种不停丰富,已经形成自动控制一支中坚力量。据统计,中国单片机年容量已达13亿片,且每十二个月以大约16速度增加,但相对于国际市场中国拥有率还不到1。这说明单片机应用在中国有着宽广前景。对于从事自动控制技术人员来讲,掌握单片机原理及其应用已经成为必不可少学习任务。 单片机应用十分广泛,在工业控制领域、家电产品、智能化仪器仪表、计算机外部设备,尤其是机电一体化产品中,全部相关键用途。其关键用途能够分为以下方面。l 显示:经过单片机控制发光二极管或是液晶,显示特定图形和字符。l 机电控制:用单片机控制机电产品做定时或定向动作。l 检测:经过单片机和传感器联合使用,用来检测产品或工况意外发生。l 通信:经过RS-232串行通信或是USB通信,传输数据和信号。l 科学计算:用来实现简单算法。那么单片机是不是处理上述应用唯一选择呢?当然不是!单片机最显著优点是价格廉价,从几元人民币到几十元人民币。这是因为这类芯片生产量很大,技术也很成熟。其次,单片机体积也远小于其它两种方案。单片机本身通常见40引脚封装,当然功效多部分单片机也有引脚比较多,如68引脚,功效少只有10多个或20多个引脚,有甚至只有8只引脚。当然,单片机不管在速度还是容量方面全部小于其它两种方案,不过在实际工作中并不是任何需要计算机场所全部要求计算机有很高性能。比如,控制电冰箱控制器就不需要使用嵌入式系统,用一片51就能够轻松实现。所以应用关键是看能否够用,是否有很好性能价格比。51系列单片机已经面世十多年,仍然没有被淘汰,还在不停发展中,这就说明是它有宽广应用前景。第二章 系统总体设计2.1 课程设计任务 基于单片机出租车模拟计价器,采取at24c02存放芯片+LCD1602液晶显示等设计而成。用24c02来存放单价,经过按键来模拟增加里程,模拟出租车向前开。经过液晶显示器显示目前行驶状态、行驶公里、行驶时间时间(时、分、秒)、费用、单价、等信息。能够设置每公里单价,和夜间单价和白天单价不一样模式,设置后掉电无需重新设置,设置有等候/继续计时模式。计费分行走里程*单价+等候时间*价格。2.2 课程设计方案方案一:采取数字电子技术,利用555定时芯片组成多谐振荡器,或采取外围晶振电路作为时钟脉冲信号,采取计数芯片对脉冲尽心脉冲计数和分频,最终经过译码电路对数据进行译码,将译码所得数据送给数码管显示,一下是该方案步骤框图,方案一图1.1所表示:时钟脉冲等候信号公里脉冲计费脉冲计时计费译码数码管显示图1方案一 方案二:采取EDA技术,依据层次化设计理论,该设计问题自顶向下可分为分频模块,控制模块 计量模块、译码和动态扫描显示模块,其系统框图图2所表示:时钟信号等候信号公里脉冲计费/复位分频器控制器计费计时计程译码显示图2方案二方案三:采取MCU技术,经过单片机作为主控器,利用1602字符液晶作为显示电路,采取外部晶振作为时钟脉冲,经过按键能够方便调整,一下是方案三系统步骤图,本方案关键是必需对于数字电路比较熟悉,成本又高。方案图图3所表示:STC89C521602液晶LED灯电源电路按键电路复位电路图3方案三方案总结:经过各个方案比较此次采取方案三,不仅控制简单,而且成本低廉,设计电路简单。第三章 系统硬件设计3.1 振荡电路 单片机内部有一个高增益、反相放大器,其输入端为芯片引脚XTAL1,其输出端为引脚XTAL2。经过这两个引脚在芯片外并接石英晶体振荡器和两只电容(电容和通常取20pF)。这么就组成一个稳定自激振荡器。 振荡电路脉冲经过二分频后作为系统时钟信号,再在二分频基础上三分频产生ALE信号,此时得到信号时机器周期信号。振荡电路图4所表示:图4振荡电路3.2 复位电路设计 复位操作有两种基础形式:一个是上电复位,另一个是按键复位。按键复位含有上电复位功效外,若要复位,只要按图中RESET键,电源VCC经电阻R1、R2分压,在RESET端产生一个复位高电平。上电复位电路要求接通电源后,经过外部电容充电来实现单片机自动复位操作。上电瞬间RESET引脚取得高电平,伴随电容充电,RERST引脚高电平将逐步下降。RERST引脚高电平只要能保持足够时间(2个机器周期),单片机就能够进行复位操作。按键复位电路图图5所表示。 图5复位电路3.3 键盘接口电路 (1) 独立式键盘:独立式键盘中,每个按键占用一根I/O口线,每个按键电路相对独立。I/O口经过按键和地相连,I/O口有上拉电阻,无键按下时,引脚端为高电平,有键按下时,引脚电平被拉低。I/O口内部有上拉电阻时,外部可不接上拉电阻。键盘接口电路图6所表示: 图6键盘接口电路3.4 显示电路3.4.1 1602LCD基础参数及引脚功效1602LCD分为带背光和不带背光两种,基控制器大部分为HD44780,带背光比不带背光厚,是否带背光在应用中并无差异,二者尺寸差异图7所表示。 图7 LM016L结构图LCD1602关键技术参数: 容量:16×2个字符芯片工作电压:4.55.5V工作电流:2.0mA(5.0V)模块最好工作电压:5.0V字符尺寸:2.95×4.35(W×H)mm引脚功效说明:1602LCD采取标准14脚(无背光)或16脚(带背光)接口,各引脚接口说明如表1所表示: 表1引脚接口说明表编号符号引脚说明编号符号引脚说明1VSS电源地9D2数据2VDD电源正极10D3数据3VL液晶显示偏压11D4数据4RS数据/命令选择12D5数据5R/W读/写选择13D6数据6E使能信号14D7数据7D0数据15BLA背光源正极8D1数据16BLK背光源负极第1脚:VSS为地电源。第2脚:VDD接5V正电源。第3脚:VL为液晶显示器对比度调整端,接正电源时对比度最弱,接地时对比度最高,对比度过高时会产生“鬼影”,使用时能够经过一个10K电位器调整对比度。第4脚:RS为寄存器选择,高电平时选择数据寄存器、低电平时选择指令寄存器。第5脚:R/W为读写信号线,高电平时进行读操作,低电平时进行写操作。当RS和R/W共同为低电平时能够写入指令或显示地址,当RS为低电平R/W为高电平时能够读忙信号,当RS为高电平R/W为低电平时能够写入数据。第6脚:E端为使能端,当E端由高电平跳变成低电平时,液晶模块实施命令。第714脚:D0D7为8位双向数据线。第15脚:背光源正极。第16脚:背光源负极。 3.4.2 显示模块采取1602液晶显示接口电路 图8显示电路 3.5 单片机各引脚功效说明 下面对STC89C52各引脚功效进行较为具体介绍:1)电源引脚Vcc和Vss Vcc(40脚):电源端为+5V Vss(20脚):接地端。 2)时钟电路引脚XTAL1和XTAL2XTAL2(18脚):接外部晶体和微调电容一端。在单片机内部它是振荡电路反向放大器输出端,振荡电路频率就是晶体固有频率。若需采取外部时针电路时,该引脚输入外时钟脉冲。要检验89C52振荡电路是否正常工作,可用示波器查看XTAL2端是否有脉冲信号输出。XTAL1(19脚):接外部晶体和微调电容另一端。在片内,它是振荡电路反向放大器输入端。在采取外部时钟时,该引脚必需接地。 3)控制信号脚 RST ALE PSEN 和EA。 RST(9脚):RST是复位信号输入端,高电平有效。在此输入端保持两个机器周期(24个时钟振荡周期)高电平时,就能够完成复位操作。ALE/PROG(30引脚):地址锁存许可信号端。当STC89C52上电正常工作后,ALE引脚不停向外输出正脉冲信号。此频率为振荡器频率fosc1/6,当CPU访问片外存放器时,ALE输出信号作为锁存低8位地址控制信号。在CPU访问片外数据存放时,每取值一次(一个机器周期)会丢失一个脉冲。平时不访问片外存放时,ALE端也以1/6振荡频率固定输出正脉冲,所以ALE信号能够用作对外输出时钟或定时信号。假如你想看一下STC89C52芯片好坏,可用示波器查看ALE端是否有脉冲信号输出,如有脉冲信号输出,则STC89C52基础上是好。ALE负载驱动能力为8个LS型TTL(低功耗高速TTL)。 PSEN(29脚);程序存放许可输出信号引脚,在访问片外程序存放器时,此端定时输出负脉冲作为读片外存放器选通信号。此引脚接ERROMOE端。PSEN端有效,即许可读出ERROM/ROM中指令码。CPU在从外部ERROM/ROM取指令期间,每个周期PSEN两次有效。不过,在访问片外RAM时,要少产生两次PSEN负脉冲信号。要检验一个STC89C52小系统上电后CPU能否正常到ERROM/ROM中读取指令码,也可用于示波器看PSEN端有没有脉冲输出。如有,说明基础上工作正常。EA/VPP(31脚):外部程序存放器地址许可输入端/固化编程电压输入端。当EA引脚接高电平时,CPU只访问片内ERROM/ROM并实施内部程序存放器中指令。但在PC(程序计数器)值超出OFFFH(对8751/8051为4k)时,将自动转向实施片外存放器程序。当出入信号EA引脚接低电平(接地)时,CPU只访问外部ERROM/ROM并实施外部程序存放器中指令,而不管是否有片内程序存放器。对于无芯片内ROM8031或8032,须外扩ERROM,此时必需将EA引脚接地。假如使用有片内ROMSTC89C52,外扩ERROM也是能够,但也要使EA接地。4)I/O(输入/输出端口,P0,P1,P2,P3)P0口:P0口是一个漏极开路8位准双向I/O端口。P1口:8位准双向I/O端口。P2口:即能够做地址总线输出地址高8位,也能够做一般I/O用,(此时为准双向口)。P3口:双功效口,即能够做一般I/O口用(此时为准向口,也能够按每位定义实现第二功效操作)。见表1。表2 P3口第二功效表引脚第二功效P3.0RXD (串行输入口)P3.1TXD (串行输出口)P3.2INT0(外部中止0)P3.3INT1(外部中止1)P3.4T0(定时器0外部中止)P3.5T1(定时器1外部中止)P3.6WR(外部存放器写选通)P3.7RD(外部存放器读写通)第四章 系统软件设计4.1 单片机资源使用在此次设计中像电路键盘用到了P2口,其中P2.0到P2.5口作为键盘输入,显示电路用到了P1和P3口,P1口为液晶数据口。4.2 单片机软件模块设计4.2.1 中止子函数对于中止程序,只要定时器计数满就会产生中止50ms中止一次,累计20次,秒钟加1,秒钟计满再分钟加,当分钟加到99时全部清零。以下是中止子函数步骤图图9所表示:图9中止子程序步骤图4.2.2 判键子函数 对于独立式键盘判键,首先看有键按下不,假如有键按下则延时一会儿,在判定是否真有键按下,假如确实有键按下,在判键释放,最终实施键功效程序。判键子函数步骤框图图10所表示: 图10判键子程序步骤图4.2.3 显示子程序 1602液晶是字符型液晶,它内部自带字符库,它能够写两行字符,同时每行能够写40个字符,在写显示程序时候,我们先写命令,再设定字符显示,最终写数据,在每写一次命令或数据全部需要判定液晶是否忙。液晶显示程序步骤图图11所表示: 图11显示子程序步骤图4.3 总程序步骤框图整体程序步骤框图图12所表示: 图12整体程序步骤框图第五章 系统调试过程本设计需要用Keil uVision2对C51程序进行编译,生成“.hex”文件,以下图:图13 Keil uVision2对C51程序进行编译 在Proteus软件中画出仿真电路(图),把Keil uVision2编译后生成“.hex”导入到单片机中,按“运行仿真”键进行仿真。图14 仿真图第六章 设计效果(实物图或仿真效果图)图15 仿真效果图第七章 结论总结作为一名电信专业大三学生,我认为做单片机课程设计是十分有意义,而且是十分必需。在已度过大课时间里,我们大多数接触是专业课。我们在课堂上掌握仅仅是专业课理论知识,怎样去锻炼我们实践能力?怎样把我们所学专业基础课理论知识利用到实践中去呢?我想做类似课程设计就为我们提供了良好实践平台。 单片机作为我们关键专业课之一,即使在大三开学初我对这门课并没有什么爱好,认为那些程序枯燥乏味,但在这次课程设计后我发觉自己在一点一滴努力中对单片机爱好也在逐步增加。 经过这次设计,我知道了学习关键性,了解到理论知识和实践相结合关键意义,学会了坚持、耐心和努力,这将为自己以后学习和工作做出了最好楷模。我认为作为一名电信专业学生,单片机课程设计是很有意义。更关键是怎样把自己平时所学东西应用到实际中。 即使自己对于这门课懂并不多,很多基础东西全部还没有很好掌握,认为极难,也没有很有效措施经过本身去了解,不过靠着这一个多礼拜“学习”,在小组同学帮助和讲解下,逐步对这门课逐步产生了些许爱好,自己开始主动学习并逐步从基础慢慢开始弄懂它。 我认为这个收获应该说是相当大。认为课程设计反应是一个从理论到实际应用过程,不过更远一点能够联络到以后毕业以后从学校转到踏上社会一个过程。小组人员配合相处,和本身动脑和努力,全部是以后工作中需要。参考文件1 李广弟,朱月秀,冷祖祁.单片机基础M.第3版.北京航空航天大学出版社,1月2李华.MCS-51系列单片机实用接口技术M.北京航空航天大学出版社,19963 马忠梅,张凯,马岩,单片机C语言应用程序设计,M,北京:北京航空航天大学出版社,.11;4 胡辉,单片机原理及应用设计二十一世纪高等院校计划教材M,水利水电出版社,.7;5 刘守义,单片机应用技术M,西安:西安电子科技大学出版社,1996.8;致谢 本课程设计是在石蕊老师悉心指导下完成,石老师渊博学识和丰富经验给我留下了深刻印象。从石老师那里我学到不仅是专业知识和实际问题科学处理方法,更为关键是勤奋和严谨治学精神和对学生认真负责,老师谆谆教育使我受益匪浅,在此向石老师表示衷心感谢并致以高尚敬意!感谢家人给我学业上和生活上支持和照料。同时感谢给我帮助各位老师、同学和好友们!附录1 程序清单#include <reg52.h> /调用单片机头文件#define uchar unsigned char /无符号字符型 宏定义变量范围0255#define uint unsigned int /无符号整型 宏定义变量范围065535uchar miao,fen = 0,shi;uchar flag_bai_hei; /白天晚上标志位uchar value;uint bai_3l_price = 60; /白天3千米内单价 6元uint bai_3w_price = 18; /白天3千米外单价/千米 1.8元uint bai_wait_price = 5; /白天等候时单价/分钟 0.5元uint wan_3l_price = 70; /晚上3千米内单价/千米 7元uint wan_3w_price = 22; /晚上3千米外单价/千米 2.2元uint wan_wait_price = 10; /晚上等候时单价/分钟 1元uint distance = 0; /行使距离uint zong_jia; /总价bit flag_300ms = 0;bit flag_1s ;bit flag_time_en = 0;#include "lcd1602.h"/*1ms延时函数*/void delay_1ms(uint q)uint i,j;for(i=0;i<q;i+)for(j=0;j<120;j+);#include "iic.h"void write_iic_data()write_24c02(0,flag_bai_hei);write_24c02(1,bai_3l_price % 256); /保留数据write_24c02(2,bai_3l_price / 256); /保留数据write_24c02(3,bai_3w_price % 256); /保留数据 write_24c02(4,bai_3w_price / 256); /保留数据 write_24c02(5,bai_wait_price % 256); /保留数据 write_24c02(6,bai_wait_price / 256); /保留数据 write_24c02(7,wan_3l_price % 256); /保留数据write_24c02(8,wan_3l_price / 256); /保留数据write_24c02(9,wan_3w_price % 256); /保留数据 write_24c02(10,wan_3w_price / 256); /保留数据 write_24c02(11,wan_wait_price % 256); /保留数据 write_24c02(12,wan_wait_price / 256); /保留数据 /*自动初始化保留数据*/ void zidong_chushifa_iic()value = read_24c02(200);value = read_24c02(200);if(value != 0x91)/新单片机初始单片机内问EEPOMvalue = 0x91;write_iic_data();write_24c02(200,value); /保留数据delay_1ms(300);/*读出来保留数据*/ void read_iic_data()flag_bai_hei = read_24c02(0);bai_3l_price = read_24c02(2);bai_3l_price = bai_3l_price * 256 + read_24c02(1);bai_3w_price = read_24c02(4);bai_3w_price = bai_3w_price * 256 + read_24c02(3);bai_wait_price = read_24c02(6);bai_wait_price = bai_wait_price * 256 + read_24c02(5);wan_3l_price = read_24c02(8);wan_3l_price = wan_3l_price * 256 + read_24c02(7);wan_3w_price = read_24c02(10);wan_3w_price = wan_3w_price * 256 + read_24c02(9);wan_wait_price = read_24c02(12);wan_wait_price = wan_wait_price * 256 + read_24c02(11);/*独立按键处理函数*/ #define key_io P2uchar key_can;void key()static uchar key_new = 0,key_old = 0,key_value = 0;key_io |= 0x3f;if(key_new = 0) /按键松开if(key_io & 0x3f) = 0x3f)key_value +;else key_value = 0;if(key_value >= 5) /按键松开松手检测key_value = 0;key_new = 1;/按键松开后进入等候按键状态else if(key_io & 0x3f) != 0x3f) /按键按下key_value +;else key_value =0;if(key_value >= 5)/按键按下消抖key_value = 0;key_new = 0; /按键松开后进入等候松开按键状态key_can = 20;if(key_new = 0) && (key_old = 1)switch(key_io & 0x3f)case 0x3e: key_can = 1; break; /得到按键值 case 0x3d: key_can = 2; break; /得到按键值 case 0x3b: key_can = 3; break; /得到按键值 case 0x37: key_can = 4; break; /得到按键值 case 0x1f: key_can = 5; break; /得到按键值 case 0x2f: key_can = 6; break; /得到按键值 /write_sfm2(2,0,key_can); /按键按下显示按键值 key_old = key_new; #include "menu.h"/*对应菜单内处理函数*/void menu_dis()if(menu_1 = 0)if(key_can = 6)distance +;write_sfm4(1,0,distance); if(key_can = 5) /清零 从新计价flag_time_en = 0;shi = 0;fen = 0;miao = 0;zong_jia = 0;distance = 0;if(key_can = 2)flag_time_en = flag_time_en;if(flag_300ms = 1)flag_300ms = 0;if(distance <= 30)/3公里内价格if(flag_bai_hei = 0)if(fen <= 3)zong_jia = bai_3l_price;else zong_jia = bai_3l_price + (shi * 60 + fen - 3) * bai_wait_price;else if(fen <= 3)zong_jia = wan_3l_price; else zong_jia = wan_3l_price + (shi * 60 + fen - 3) * bai_wait_price;else /3公里外价格if(flag_bai_hei = 0)if(fen <= 3)zong_jia = bai_3l_price + bai_3w_price * (distance - 30) / 10 ;else zong_jia = bai_3l_price + bai_3w_price * (distance - 30) / 10 + (shi * 60 + fen - 3) * bai_wait_price;else if(fen <= 3)zong_jia = wan_3l_price + wan_3w_price * (distance - 30) / 10 ;else zong_jia = wan_3l_price + wan_3w_price * (distance - 30) / 10 + (shi * 60 + fen - 3) * wan_wait_price;if(flag_bai_hei = 0)write_sfm2_dian(2,9,bai_3w_price);else write_sfm2_dian(2,9,wan_3w_price);write_sfm2(2,0,shi); write_sfm2(2,3,fen); write_sfm2(2,6,miao); write_sfm4(1,10,zong_jia); write_sfm4(1,0,distance); write_zifu(1,15,0x5c);/¥write_zifu(2,12,0x5c);/¥/*显示函数*/void jishu_chashu()if(flag_1s = 1) && (flag_time_en = 1)flag_1s = 0;miao+;if(miao >= 60)miao = 0;fen +;if(fen >= 60)fen = 0;shi+;if(shi >= 24)shi = 0;/*定时器0初始化程序*/void time_init() EA = 1; /开总中止TMOD = 0X01; /定时器0、工作方法1ET0 = 1; /开定时器0中止 TR0 = 1; /许可定时器0定时void main()init_1602();init_1602_dis_csf(); zidong_chushifa_iic();read_iic_data();time_init();init_menu();while(1)key();if(key_can < 20)key_with();menu_dis();jishu_chashu();/*定时器0中止服务程序*/void time0_int() interrupt 1static uchar value;TH0 = 0x3c;TL0 = 0xb0; / 50msvalue +;if(value % 6 = 0)flag_300ms = 1;if(value >= 20)flag_1s = 1;value = 0;附录2 元器件清单 表3元器件清单 名称规格数量备注 电阻 2001个1K1个10K5个1002个 电容20pF2个10F2个极性电容 发光二极管3个 按键7个直流电机1个 晶振12MHz1个 芯片STC89C521块1602液晶1块内带字符库