河南理工大学单片机课程设计论文出租车计价器.docx
《河南理工大学单片机课程设计论文出租车计价器.docx》由会员分享,可在线阅读,更多相关《河南理工大学单片机课程设计论文出租车计价器.docx(30页珍藏版)》请在冰豆网上搜索。
河南理工大学单片机课程设计论文出租车计价器
河南理工大学
《单片机应用与仿真训练》设计报告
题目:
出租车计价器设计
姓名:
学号:
3
专业班级:
电气班
指导老师:
所在学院:
电气工程与自动化学院
年5月20日
摘要
本设计用直流电机转动模拟出租车车轮转动,实现出租车多功能的计价器功能。
设计采用AT89S52单片机为主控芯片,用霍尔传感器检测电机转盘转速,采用AT24C02芯片使系统在掉电时路程、单价等重要信息的存储保护,采用两个四位8段共阴数码显示管里程、总价格和等待时间等信息。
本设计可以实现单双程设置、系统暂停和清零、空车指示、信息显示、显示切换、掉电保护等功能。
出租车计价是根据车所行驶的路程以及乘客乘车的方式综合决定的。
出租车行驶总路程可以通过车轮的周长乘车轮旋转圈数得到。
即可计算得到车轮旋转几周出租车能行驶一公里的路程。
使用霍尔传感器方便地计量车轮旋转的圈数。
输出的脉冲信号被接入到AT89S52单片机系统中,通过计算接收到的脉冲个数,计算出当前所行驶的路程,并且可以计算实时的速度,在速度低于5公里每小时是进入等待计费。
与此同时,根据不同的收费标准,通过选择相应的起步价、单价等收费标准进行计算。
通过键盘能够实现往返设置,启动、暂停、停止计价器以及切换显示当前的行驶里程和需支付的车费。
本设计硬件电路总体可以分为五个单元:
单片机最小系统单元,指示灯电路单元,按键电路单元,路程时间与金额显示单元,转速信号接收单元。
软件系统可以大致分为五个大的模块为:
总初始化模块,按键扫描模块,中断与定时模块,数据计算模块,数码管显示模块。
其中,键盘扫描和数码管显示采用查询方式,转速信号接收与等待记时采用中断方式。
这些软硬件系统构成了最终的设计。
关键字:
多功能计价器;AT89S52;AT24C02;霍尔传感器;显示切换
目录
1概述1
1.1功能要求1
1.2设计参数1
1.3系统原理1
2系统总体方案及硬件设计3
2.1系统总体方案3
2.2单片机最小系统单元3
2.3转动信号采集单元5
2.4显示单元6
2.5指示灯单元7
2.6按键输入电路单元7
2.7IO分配表8
3软件设计9
3.1总体流程9
3.2计算模块9
3.3键盘扫描9
3.4显示程序9
4Proteus软件仿真10
5课程设计体会11
参考文献:
12
附1源程序代码13
附2系统原理图25
1概述
1.1功能要求
基本要求:
(1)能显示里程,单位为公里,最后一位为小数位。
(2)能显示金额数,单位为元,最后一位为小数位。
(3)可设定单程价格和往返价格,单程价格为2元/公里,往返价格为1.5元/公里。
(4)车速<5公里/小时的时间累积为总等待时间,每5分钟等待时间相当于里程数增加1公里。
(5)起步公里数为3公里,价格为5元,若实际距离大于3公里,按规则3计算价格。
(6)按暂停键,计价器可暂停计价,按查询键,可显示总等待时间。
发挥部分:
空车指示、语音提示、信息存储等。
1.2设计参数
由于要求没有给出车轮的相关参数,所以这里进行一些基本参数的查询。
据调查统计,现行出租车轮胎直径大致有四种,直径分别为520mm、540mm、560mm和580mm.
本作品针对560mm的出租车进行设计。
它的周长为:
1.7584m,57圈行驶100m。
1.3系统原理
出租车计价器是乘客与司机双方的交易准则,它是出租车行业发展的重要标志。
它关系着交易双方的利益,具有良好性能的计价器无论是对广大出租车司机朋友还是乘客来说都是很必要的。
因此,汽车计价器的研究也是十分有应用价值和现实意义的。
出租车计价是根据车所行驶的路程以及乘客乘车的方式综合决定的。
出租车行驶总路程可以通过车轮的周长乘车轮旋转圈数得到。
即可计算得到车轮旋转几周出租车能行驶一公里的路程。
使用霍尔传感器方便地计量车轮旋转的圈数。
输出的脉冲信号被接入到AT89S52单片机系统中,通过计算接收到的脉冲个数,计算出当前所行驶的路程,并且可以计算实时的速度,在速度低于5公里每小时是进入等待计费。
于此同时,根据不同的收费标准,通过选择相应的起步价、单价等收费标准进行计算。
通过键盘能够实现往返设置,启动、暂停、停止计价器以及切换显示当前的行驶里程和需支付的车费。
本设计硬件电路分为五个单元:
单片机最小系统单元,指示灯电路单元,按键电路单元,路程时间与金额显示单元,转速信号接收单元。
软件系统分为五个大的模块为:
总初始化模块,按键扫描模块,中断与定时模块,数据计算模块,数码管显示模块。
其中,键盘扫描和数码管显示采用查询方式,转速信号接收与等待记时采用中断方式。
这些软硬件系统构成了最终的设计。
2系统总体方案及硬件设计
2.1系统总体方案
本设计可以分为五个单元,分别为:
单片机最小系统单元、转速信号接收单元、路程时间与金额显示单元、指示灯电路单元、按键输入电路单元。
系统框图如图1所示:
图1系统框图
2.2单片机最小系统单元
主控机系统采用了Atmel公司生产的AT89S52单片机,它含有256字节数据存储器,内置8K的电可擦除FLASHROM,可重复编程,大小满足主控机软件系统设计。
AT89S52主要功能列举如下:
1、拥有灵巧的8位CPU和在系统可编程Flash
2、晶片内部具时钟振荡器(传统最高工作频率可至12MHz)
3、内部程序存储器(ROM)为8KB
4、内部数据存储器(RAM)为256字节
5、32个可编程I/O口线
6、8个中断向量源
7、三个16位定时器/计数器
8、三级加密程序存储器
9、全双工UART串行通道。
AT89S51芯片的40个引脚功能分别为:
VCC电源电压。
GND接地。
RST复位输入。
当RST变为高电平并保持2个机器周期时,将使单片机复位。
WDT溢出将使该引脚输出高电平,设置SFRAUXR的DISRTO位(地址8EH)可打开或关闭该功能。
DISKRTO位缺省为RESET输出高电平打开状态。
ALE/PROG:
当访问外部存储器时,地址锁存允许的输出电平用于锁存地址的地位字节。
在FLASH编程期间,此引脚用于输入编程脉冲。
在平时,ALE端以不变的频率周期输出正脉冲信号,此频率为振荡器频率的1/6。
因此它可用作对外部输出的脉冲或用于定时目的。
然而要注意的是:
每当用作外部数据存储器时,将跳过一个ALE脉冲。
如想禁止ALE的输出可在SFR8EH地址上置0。
此时,ALE只有在执行MOVX,MOVC指令是ALE才起作用。
另外,该引脚被略微拉高。
如果微处理器在外部执行状态ALE禁止,置位无效。
/PSEN:
外部程序存储器的选通信号。
在由外部程序存储器取指期间,每个机器周期两次/PSEN有效。
但在访问外部数据存储器时,这两次有效的/PSEN信号将不出现。
/EA/VPP:
当/EA保持低电平时,则在此期间外部程序存储器(0000H-FFFFH),不管是否有内部程序存储器。
注意加密方式1时,/EA将内部锁定为RESET;当/EA端保持高电平时,此间内部程序存储器。
在FLASH编程期间,此引脚也用于施加12V编程电源(VPP)。
XTAL1反向振荡放大器的输入及内部时钟工作电路的输入。
XTAL2来自反向振荡放大器的输出。
P0口:
一组8位漏极开路型双向I/O口。
也即地址/数据总线复用口。
作为输出口用时,每位能驱动8个TTL逻辑门电路,对端口写“1”可作为高阻抗输入端用。
在访问外部数据存储器或程序存储器时,这组口线分时转换地址(低8位)和数据总线复用,在访问期间激活内部上拉电阻。
在Flash编程时,P0口接收指令字节,而在程序校验时,输出指令字节,校验时,要求外接上拉电阻。
P1口:
一个带内部上拉电阻的8位双向I/O口,P1的输出缓冲级可驱动(吸收或输出电流)4个TTL逻辑门电路。
对端口写“1”,通过内部的上拉电阻把端口拉到高电平,此时可作输入口。
作输入口使用时,因为内部存在上拉电阻,某个引脚被外部信号拉低时会输出一个电流。
Flash编程和程序校验期间,P1接收低8位地址。
P2口:
一个带内部上拉电阻的8位双向I/O口。
P1的输出缓冲级可驱动(吸收或输出电流)4个TTL逻辑门电路。
对端口写“1”,通过内部的上拉电阻把端口拉到高电平,此时可作输入口。
作输入口使用时,因为内部存在上拉电阻,某个引脚被外部信号拉低时会输出一个电流。
在访问外部程序存储器或16位地址的外部数据存储器时,P2口送出高8位地址数据。
在访问8位地址的外部数据存储器时,P2口线上的内容在整个访问期间不改变。
Flash编程和程序校验期间,P2亦接收低8位地址。
P3口:
一个带内部上拉电阻的8位双向I/O口。
P3的输出缓冲级可驱动(吸收或输出电流)4个TTL逻辑门电路。
对P3口写“1”时,它们被内部的上拉电阻把拉到高电并可作输入端口。
作输入端口使用时,被外部拉低的P3口将用上拉电阻输出电流。
P3口除了作为一般的I/O口线外,还作特殊功能口。
P3口的第二功能引脚分配如下:
P3.0:
RXD,串行通信输入。
P3.1:
TXD,串行通信输出。
P3.2:
INT0,外部中断0输入。
P3.3:
INT1,外部中断1输入。
P3.4:
T0,计时计数器0输入。
P3.5:
T1,计时计数器1输入。
P3.6:
WR:
外部数据存储器的写入信号。
P3.7:
RD,外部数据存储器的读取信号。
单片机最小系统原理图如图2所示。
2.3转动信号采集单元
转动信号采集是利用霍尔传感器来实现的,转轮每转动一周,霍尔传感器发出一个脉冲,然后发给单片机的外部中断0端口P3.2,通过中断来接受传感器的信号。
此模块的模型如图3所示。
图2单片机最小系统原理图
图3转动信号采集单元模型
2.4显示单元
采用两个四位8段共阴数码显示,一组显示金额,另一组显示路程与等待时间配合按键来切换。
数据位选用单片机P0口,片选端分别接在P2口的高四位和低四位。
它们的连线如图4所示。
图4显示单元原理图
2.5指示灯单元
本设计按照功能要求设置了五个LED灯。
原理接线图如图5所示。
各个LED灯的功能分别为:
led0:
空车指示;
led1:
指示单程还是双程,当选择双程计费时亮;
led2:
指示显示的是路程还是等待时间,显示等待时间时亮;
led3:
指示系统暂停与否,当选择暂停时亮;
led4:
指示堵车与否,堵车指示时灯亮。
图5指示灯单元原理图图6按键输入电路单元原理图
2.6按键输入电路单元
本设计按照功能要求设置了五个按键。
其功能分别为:
key0:
系统清零,用来将整个计费系统的显示清零;
key1:
单程双程,用来设置是单程还是往返计费;
key2:
显示切换,用来切换路程与等待时间的显示;
key3:
系统暂停,用来将整个计费系统暂停;
key4:
掉电数据恢复。
2.7IO分配表
根据以上分析,总体IO分配如表1所示。
表1IO分配表
IO口
功能
输入
P3.2/INT0
转动信号采集输入
P3.0-1、P1.5-7
按键输入S0-S5
输出
P0
数码管显示段选
P2
数码管显示位选
P1.0-4
发光二极管LED0-LED5
P3.6
AT24C02芯片SDA
P3.7
AT24C02芯片SCL
3软件设计
3.1总体流程
软件系统可以大致分为五个大的模块为:
总初始化模块,按键扫描模块,中断与定时模块,数据计算模块,数码管显示模块。
其中,键盘扫描和数码管显示采用查询方式,转速信号接收与等待记时采用中断方式。
3.2计算模块
计算程序根据里程数分别进入不同的计算公式。
如果里程大于3公里,则执行公式:
总金额=起步价+(里程-3)*单价+等待时间*等待单价;否则,执行公式:
总金额=起步价+等待时间*等待单价。
对于里程数采用外部中断零来记录,车轮没转一周,霍尔传感器发一个脉冲然后进入中断子程序,对相应的变量进行更新。
对于速度的判断及等待时间的记录采用定时器零中断,设定10ms一个中断,然后判断车速,小于5公里/小时时,则开始记录等待时间。
3.3键盘扫描
键盘扫描才用查询方式,当有按键按下时就对相应的标志进行取反,或调用其他子函数,在消抖过程中,这里将数码管显示程序潜入以保证显示的稳定。
3.4显示程序
显示程序利用主函数内的循环,实现动态扫描显示,同时根据数码管余辉和人眼暂留现象,即可实现显示。
本设计采用两个四个一组的八位数码管来显示,一组显示金额,另一组显示路程与等待时间配合按键来切换。
数据端都用单片机P1口,片选端分别接在P2口的高四位和低四位。
4Proteus软件仿真
将整个系统原理图在Proteus连接好后,下载如编写好的程序仿真如下:
如图显示的状态设置为:
单程,车速大于5km/h,当路程等于40.4km时的显示情况。
5课程设计体会
本次单片机课程设计,我们选的题目是出租车计价器的设计。
通过仿真、焊接、调试等不断的努力,我们的出租车计价器实现了基本要求的全部功能和发挥部分的部分功能。
比如能显示里程、金额数、总等待时间,可设定单程价格和往返价格,按暂停键,计价器可暂停计价,按查询键,可显示总等待时间,空车指示、信息存储等。
经过这些天有关于出租车计价器的课程设计,使我对MCS-51系列单片机的应用有了更深的了解。
从前的学习过程过于浮浅,只是流于表面的理解,而现在要做课程设计,就不得不要求我们对所用到的知识有更深层次的理解。
因为课程设计的内容比及书本中的理论知识而言,更接近于现实生活,而理论到实践的转化往往是一个艰难的过程,它犹如一只拦路虎,横更在我们的面前。
但是我们毫不畏惧,因为我们相信我们能行。
事情并不总是一帆风顺的,我们总会遇到困难和险阻。
在此次课程设计的过程中,我们碰到了许多的问题。
比如,对于数码管动态扫描显示和键盘的延时防抖的综合编程不能较好地解决;对于代码的前后顺序及调用掌握得还不够好;对于一些相关的应用软件(KEIL、PROTEUS、Altiumdesigner09)没能熟练掌握。
当然,问题并不可怕,只要我们怀着一颗不服输的心,勇往直前,那么胜利将不会离我们太远。
通过上网查找资料、与同学老师交流、小组成员间的讨论、不断实践与探索,我们总能找到解决问题的方法,最后得到良好的效果。
通过这次课程设计使我懂得了理论与实际相结合是很重要的,只有理论知识是远远不够的,只有把所学的理论知识与实践相结合起来,从理论中得出结论,才能真正为社会服务,从而提高自己的实际动手能力和独立思考的能力。
同时在设计的过程中发现了自己的不足之处,对以前所学过的知识理解得不够深刻,掌握得不够牢固。
这期间,我们最大的收获就是自己的动手能力和独立解决问题的能力得到了很大的提高,也充分体会到了自己设计东西的乐趣、学会查阅资料和对别人的东西融会变通的重要性,也明白了很多知识光靠趴在书本上学是学不到其中的精髓的,必须亲自去试着实践,亲自去经历才能对它们真正的掌握,凡事都要自己去动下手,去实践一下,遇到困难,永远不要沮丧气馁。
在动手的过程中,不仅能增强实践能力,而且在理论上可以有更深的认识;这次设计给了我们极大的鼓舞和信心,相信在以后的学习中可以通过不断的摸索和实践来提高其他方面的知识。
总之,本次课程设计让我们更加深刻的掌握了MCS-51系列单片机的工作原理和编程语言,更加熟练的掌握了KEIL、PROTEUS、Altiumdesigner09等专业软件的使用,熟悉了产品开发的大致流程,深刻的体会到了团队协作精神的重要性,培养了我们发现问题、独立思考问题、多种途径解决问题的能力,锻炼并提高了了我们的动手实践能力和理论与实践相结合的能力。
我们以后一定会更加努力地进行学习和实践,做到学以致用,把知识学活,做一个动手能力强的大学生。
参考文献:
[1]谭浩强著.C程序设计[M].北京:
清华大学出版社,2005.
[2]张友德、赵志英、涂时亮著.单片微型机原理、应用与实验[M].上海:
复旦大学出版社,2006.
[3]吴戈、李玉峰编著.案例学单片机C语言开发[M].北京:
人民邮电出版社,2008.
[4]孙余凯.传感器应用电路300例[M].北京:
电子工业出版社,2008.
[5]田立.51单片机C语言程序设计快速入门[M].北京:
人民邮电出版社,2007
[6]郭天祥著.新概念51单片机C语言教程入门、提高、开发、拓展全攻略[M].北京:
电子工业出版社,2009.
[7]余发山,王福忠.单片机原理及应用技术[M].徐州:
中国矿业大学出版社,2008.
附1源程序代码
#include
#include
#include
#defineucharunsignedchar
#defineuintunsignedint
ucharcodetable_du[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
ucharcodetable_we[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};
uchartt,aa;
ucharquanshu;
ucharsecond,minute;//等待时间
uintround;//路程,单位100m
ucharround_24c02[2];
uintdistance;//走过距离,单位100m
uintprice,cost;//单价,总价钱
uintwait;//等待时间/秒
ucharqian,bai,shi,ge;//显示数据各个位置数字的临时变量
sbitkey0=P3^1;//清零(空车)/载客
sbitkey1=P3^0;//单程还是往返设置
sbitkey2=P1^7;//切换显示路程与等待时间
sbitkey3=P1^6;//暂停
sbitkey4=P1^5;//掉电数据恢复
sbitled0=P1^0;//空车指示时,灯亮。
sbitled1=P1^1;//双程指示时,灯亮。
sbitled2=P1^2;//显示等待时间时,灯亮。
sbitled3=P1^3;//暂停指示时,灯亮。
sbitled4=P1^4;//堵车指示时,灯亮。
bitkey0_flag;//(空车)/载客标志位
bitkey1_flag;//单程还是往返标志位
bitkey2_flag;//路程与等待时间标志位
bitkey3_flag;//暂停标志位
bitflag;//堵车(等待)标志位
voiddelayms(unsignedintc)
{
unsignedcharb;
for(;c>0;c--)
for(b=110;b>0;b--);
}
voiddelay_dis(void)
{
unsignedcharb,c;
for(c=7;c>0;c--)
for(b=110;b>0;b--);
}
//初始化函数(刚上电时)
voidinit_data(void)
{
distance=0;
cost=0;
round=0;
second=0;
minute=0;
key0_flag=0;//空车
key1_flag=0;//单程
key2_flag=1;//路程
key3_flag=0;//正常,非暂停
flag=1;
}
voidjisuan(void)
{
wait=minute*60+second;
distance=round+wait/30;//车轮转57圈为100m,等待时间30s为100m
if(key1_flag)
price=15;//往返价格1.5元/公里
else
price=20;//单程价格2元/公里
if(distance<=30)//小于3公里
cost=50;
else
cost=price*(distance-30)/10+50;
}
//显示的辅助程序,分离一个数的各位数字
voidfenli(uinttemp)//数据的分离处理
{
if(temp>9999)
temp=9999;
qian=temp/1000;
bai=temp/100%10;
shi=temp%100/10;
ge=temp%10;
}
voidwrite(void)
{
round_24c02[0]=round&0x00ff;
round_24c02[1]=(round>>8)&0x00ff;
write_24c02(0x00,key0_flag);
write_24c02(0x01,key1_flag);
write_24c02(0x02,key2_flag);
write_24c02(0x03,key3_flag);
write_24c02(0x04,second);
write_24c02(0x05,minute);
write_24c02(0x06,round_24c02[0]);
write_24c02(0x07,round_24c02[1]);
}
voidread(void)
{
key0_flag=read_24c02(0x00);
key1_flag=read_24c02(0x01);
key2_flag=read_24c02(0x02);
key3_flag=read_24c02(0x03);
second=read_24c02(0x04);
minute=read_24c02(0x05);
round_24c02[0]=read_24c02(0x06);
round_24c02[1]=read_24c02(0x07);
round=round_24c02[1];
round=(round<<8)|round_24c02[0];
}
//数码管显示程序
voiddisplay(void)
{
uinttemp;
//-----显示路程或者等待时间----
if(key2_flag)
{
fenli(distance);
P2=table_we[7];//位选,个位
P0=table_du[ge];//段选
delay_dis();
P2=table_we[6];//位选,十位
P0=table_du[shi]|0x80;//如果是路程,点亮小数点儿
delay_dis();
P2=table_we[5];
P0=table_du[bai];
delay_dis();
P2=table_we[4];
P0=table_du[qian];
delay_dis();
}
else
{
temp=minute*100+second;
fenli(temp);
P2