基于51单片机的出租车计价器设计Word格式.docx
《基于51单片机的出租车计价器设计Word格式.docx》由会员分享,可在线阅读,更多相关《基于51单片机的出租车计价器设计Word格式.docx(23页珍藏版)》请在冰豆网上搜索。
到达目的地,便可按显示的数字收费。
出租车计价器是乘客与司机双方的交易准则,它是出租车行业发展的重要标志,是出租车中最重要的工具。
它关系着交易双方的利益。
具有良好性能的计价器无论是对广大出租车司机朋友还是乘客来说都是很必要的。
因此,汽车计价器的研究也是十分有一个应用价值的。
1、总体设计方案
1.1设计目的
(1)学习基本理论在实践中综合运用的初步经验,掌握电路设计的基本方法、设计步骤,培养综合设计与调适能力,进一步提高综合运用所学知识和设计能力的的目的。
(2)掌握C语言程序设计方法。
(3)培养实践技能,提高分析和解决实际问题的能力,并具备一定程度的设计能力。
1.2设计方案
本设计,利用单片机丰富的端口和控制的灵活性,采用AT89C52单片机为主控器,并用开关或频率信号发生器模拟车速,通过石英振荡器,LCD液晶显示和发光二级管以及单片机内部程序构成完整的出租车计价系统,基本可以实现了按运行状态计价的功能,价格调整功能。
1.3设计原理
出租车计价是根据车所行驶的路程以及乘客乘车的里程综合决定的。
出租车行驶总路程可以通过车轮的周长乘车轮旋转圈数得到。
即可计算得到车轮旋转几周出租车能行驶一公里的路程。
通过计数接收到的脉冲个数,计算出当前所行驶的路程。
同时,通过LCD液晶显示器显示当前的行驶里程、等待时间和需支付的车费。
出租车计价器用于记录里程、起步公里数与价格的关系。
模拟出租车计价器能根据总里程数、起步公里数的情况作出相应报价等。
1.4基本设计要求
本出租车自动计费,上电后显示最初的起步价,里程计费单价,等待时间计费单价,通过按键可以调节起步价,里程计费单价,等待时间计费单价。
同时具有运行,等待,暂停等状态,可以显示暂停的时间。
出租车停止后能够显示行驶的总费用。
1.5性能指标
(1)费用的计算是按行驶里程收费。
设起步价为7.00元。
(2)当里程<
3km时,按起价计算费用。
(3)当里程>
3km时,每公里按1.7元计费。
(4)等待累计时间>
2min时,按1.5元/min计费。
1.6显示功能
(1)显示行驶里程:
用两位数字显示,显示方式为“XX”,单位为km。
计程范围0-99km,精确到1km。
(2)显示等候时间:
用两位数字显示,显示方式为“XX”,单位为min。
计时范围0-59min,精确到1min。
(3)显示总费用:
用四位数字显示,显示方式为“XXX.X”,单位为元。
计价范围0-999.9元,精确到0.1元。
1.7设计方法
本设计采用AT89C52单片机为主控器,并用开关或者频率信号发生器模拟车速,利用AT89C52的定时器工作在方式1下定时实现对出租车的计时及计价设计,输出采用LCD液晶显示屏显示。
2、系统功能
2.1出租车硬件设计
图1系统的硬件设计
2.2AT89C52单片机及引脚说明
图2AT89C52引脚配置
AT89C52是51系列单片机的一个型号,它是ATMEL公司生产的。
AT89C52有40个引脚,32个外部双向输入/输出(I/O)端口,同时内含2个外中断口,3个16位可编程定时计数器,2个全双工串行通信口,2个读写口线,AT89C52可以按照常规方法进行编程,但不可以在线编程(S系列的才支持在线编程)。
其将通用的微处理器和Flash存储器结合在一起,特别是可反复擦写的Flash存储器可有效地降低开发成本。
2.3LCD1602A的简介
(1)接口信号说明如表1所示:
表11602接口信号说明
编号
符号
引脚说明
1
Vss
电源地
9
D2
DataI/O
2
VDD
电源正极
10
D3
3
VL
液晶显示偏压信号
11
D4
4
Rs
数据/命令选择端(H/L)
12
D5
5
R/W
读/写选择端(H/L)
13
D6
6
E
使能信号
14
D7
7
D0
15
BLA
背光源正极
8
D1
16
BLK
背光源负极
(2)控制器接口说明(HD44780及兼容芯片)
基本操作时序
a读状态:
输入:
Rs=L,Rw=H,E=H输出:
D0—D7=状态字
b写指令:
Rs=L,Rw=L,D0—D7=指令码输出:
无
E=高脉冲
C读数据:
Rs=H,Rw=L,E=H输出:
D0—D7=数据
d写数据:
Rs=H,Rw=L,D0—D7=数据输出:
3、单元模块设计
3.1时钟电路
时钟电路是单片机内部有一个高增益反相放大器,其输入端为芯片引脚XTAL1,其输出端为引脚XTAL2。
通过这两个引脚在芯片外并接石英晶体振荡器和两只电容(电容和一般取30pF)。
这样就构成一个稳定的自激振荡器。
复位操作是按键复位,按键复位具有上电复位功能外,若要复位,只要按图中的RESET键,电源VCC经电阻R1、R2分压,在RESET端产生一个复位高电平。
如图3所示。
图3时钟电路
3.2LED灯指示电路
运行状态指示电路采用发光二级管对运行方式进行指示,可清楚看到计价器的运行状态。
图4LED灯指示电路
3.3按键电路
按键电路:
按键电路是通过按键去调节初始选择、调节,模式选择,开始运行,终止等功能。
霍尔传感器里程计算是通过安装在车轮旁的霍尔传感器检测到的信号,送到单片机,经处理计算,送给显示单元的。
而由于本次实验室的局限不能利用霍尔传感器,所以我们利用按键来代替霍尔传感器,通过按一次键代表汽车行驶了1公里,当在行驶过程中通过按键来选择运行状态。
按键电路如图5所示。
图5按键电路
3.4液晶显示电路
液晶显示和LED灯指示电路:
显示电路对于现实电路我们采用液晶显示,液晶又分字符型和点阵型,我们使用的液晶是字符型液晶,并且带字符库的,不需要查找代码,英文字符就可以。
液晶显示电路如图6所示。
图6液晶显示电路
4、软件设计
4.1系统流程
图7出租车计价器系统流程图
4.2源程序代码
根据设计的要求,在本系统中主要有主程序和延时程序,主程序中包括中断服务程序和键盘显示子程序、计算子程序等。
现在应用更广泛的是单片机C语言,因其简单明了,故此次课程设计采用单片机C语言编程。
程序源代码如附录1所示。
5、仿真测试
5.1程序调试域运行结果
在Keil
C51
uvision4中对系统建立项目,选定合适的单片机AT89C52,创建一个计价器的新文件,并将上述的源程序进行编辑和选项操作进行编译,以生成计价器的HEX文件。
5.2运行图示
仿真开始后,首先按动初始选择按钮,
则可以在运行单价,等待单价,起步价之间切换,每按一次切换一个量,选定后可以按动初始调节按钮进行调节,调节完成后,按下开始运行按钮则开始运行,选择运行模式后开始计费,不同的运行模式会有不同的指示灯亮起,在运行过程中液晶屏会随时显示走过的路程和等待的时间,以及总的费用。
仿真图如图8所示。
5.3仿真问题分析
问题需要改进,例如本设计经过多次的调试与改正,最终达到了设计方案中的结果。
在仿真试验中各种设计要求都能够得到验证。
但由于设计的原因,本系统仍然总在一些自动化程度不够,运行模式还需要手动选择。
6、设计总结
出租车计费器系统的设计已经全部完成,能利用AT89C52单片机对出租车启动,停止,暂停等运行状态进行选择和显示,能将单价和费用适时通过LCD显示出来。
本款出租车计价器包括单价输出、单价调整、显示当前的总费用等功能。
虽然达到了基本的设计目的,但仍然存在一些问题,策划的不够全面,对单片机不够熟悉,系统编写不够简洁完善,使得计价器计费不够细致,不够人性化。
经过这次课程设计让我学会了很多的东西。
经过自己努力,基本上完成了设计要求的内容,在系统可行性分析、原理图设计等方面都作了一些实际工作,同时也遇到了一些问题,存在一些不足。
学会了怎么去查找些资料,把所找到的东西与自己的问题所结合起来并给予解决。
这次设计使我学会把以前学到的理论知识应用于实践,使我认识到理论知识与实践之间有一定的差距,只有通过不断的努力学习和实践才能很好的把理论知识应用到实践当中,也只有通过不断的实践才能加深对理论知识的理解。
7、参考文献
[1]马艳英.单片机原理及接口技术的实际应用[J].电子技术与软件工程,2013.
[2]舒涛,伍远超,李明.基于AT89S51单片机的出租车计价器系统设计[J].现代电子技术,2010.
[3]陈爱文.基于AT89C51单片机的多功能出租车计价器[J].机电工程技术,2008.
[4]翟敏焕.基于单片机的出租车计价器设计[J].现代计算机(专业版),2014.
[5]刘尧,白福忠,兰月政.基于AT89S51单片机出租车计费器的研究[J].测控技术,2013.
[6]何俊池,张婷婷,裴文龙.基于AT89S51的出租车计价器的设计[J].科技致富向导,2011.
附录
1.源程序代码
#include<
reg52.h>
#defineucharunsignedchar
#defineuintunsignedint/*定义1602读写使能端口*/
sbitrw=P2^4;
sbitrs=P2^3;
sbiten=P2^5;
sbitb=P0^7;
sbitgl=P1^0;
voidlcd_init();
//lcd设置函数
voidwr_com(ucharcommand);
//命令函数
voidwr_data(uchardata0);
//数据函数
voidlcd_clear();
//清屏函数
voidlcd_set();
//屏幕设置函数
voidbusy();
//测忙函数
voiddisplay();
//启动前显示函数
voidprintstring(uchar*s);
voiddisplay1();
//启动后显示函数
voidkey1();
//启动前按键
sbitK=P3^0;
sbitK1=P3^1;
sbitK2=P3^2;
//开始计价
sbitK3=P3^3;
//模式选择(行程/等待)
//复位用Reset
sbitg=P2^7;
sbitaa=P1^0;
//运行
sbitbb=P1^1;
//等待
sbitcc=P1^2;
//暂停
//sbitled_run=P3^0;
//sbitled_await=P3^1;
//sbitled_stop=P3^2;
bitf_start;
bitjump_in;
bitjump_out;
voidkey();
//启动后按键
/*定义液晶显示地址数组*/
ucharcodetable[]={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x70};
uchardispbuf[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
uchardispbuf1[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
ucharv,v1;
uchari,m=0;
voidinit();
voidchuli();
voidchuli1();
voiddelay(uchart);
//延时函数
voidclear();
//终止函数
voidset(ucharx);
voidset1(uchary);
ucharcommand;
ucharcount,count1;
ucharsecond,minite,second1,minite1;
unsignedinttt,tt1;
unsignedcharvalue1=70,value2=17,value3=15;
//value1=起步价,value2=超出每公里价格,value3=等待价格
unsignedintmoney;
voidmain()
{
//Init_Timer1();
//定时器中断函数
EX0=1;
//开外部中断0
IT0=1;
//采用跳变沿触发方式
init();
lcd_init();
while
(1)
{
key1();
chuli();
display();
if(jump_in==1)
jump_in=0;
key();
chuli1();
display1();
if(jump_out==1)
jump_out=0;
clear();
break;
}
}
}
voidclear()
TR0=0;
TR1=0;
money=0;
second=0;
second1=0;
minite=0;
minite1=0;
value1=70;
value2=17;
value3=15;
//led_run=1;
//led_await=1;
//led_stop=1;
v=0;
v1=0;
for(i=0;
i<
15;
i++)
dispbuf[i]=0;
dispbuf1[i]=0;
m=0;
voidinit()//中断定时
TMOD=0x11;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
TH1=(65536-50000)/256;
TL1=(65536-50000)%256;
ET0=1;
ET1=1;
EA=1;
voidt0_(void)interrupt1using0//中断1模式0用来计时秒、分
{
count++;
if(count==20)
{
count=0;
second++;
if(second==60)
minite++;
if(minite==99)
dispbuf1[0]=m/10;
dispbuf1[1]=m%10;
dispbuf1[2]=second/10;
dispbuf1[3]=second%10;
voidt1_(void)interrupt3using3//中断3模式3用来计时秒、分
count1++;
if(count1==20)
count1=0;
second1++;
if(second1==60)
minite1++;
if(minite1==99)
dispbuf1[4]=minite1/10;
dispbuf1[5]=minite1%10;
dispbuf1[6]=second1/10;
dispbuf1[7]=second1%10;
}
voidlcd_init()
wr_com(0x3c);
wr_com(0x06);
wr_com(0x0c);
wr_com(0x01);
voidwr_com(ucharcommand)//命令
busy();
rs=0;
rw=0;
P0=command;
en=1;
en=0;
voidwr_data(uchardata0)//数据
rs=1;
P0=data0;
voidbusy()//测忙函数
rw=1;
P0=0xff;
if(b!
=1)break;
voidchuli()//分离出百位十位个位
dispbuf[0]=value1/100%10;
dispbuf[1]=value1/10%10;
dispbuf[2]=value1%10;
dispbuf[3]=value2/100%10;
dispbuf[4]=value2/10%10;
dispbuf[5]=value2%10;
dispbuf[6]=value3/100%10;
dispbuf[7]=value3/10%10;
dispbuf[8]=value3%10;
voiddisplay()//初始显示函数
set(0);
printstring("
step:
"
);
wr_data(table[dispbuf[0]]);
wr_data(table[dispbuf[1]]);
."
wr_data(table[dispbuf[2]]);
set(16);
mileage:
wr_data(table[dispbuf[3]]);
wr_data(table[dispbuf[4]]);
wr_data(table[dispbuf[5]]);
set1(0);
await:
wr_data(table[dispbuf[6]]);
wr_data(table[dispbuf[7]]);
wr_data(table[dispbuf[8]]);
set1(16);
run:
"
wr_da