课程设计说明书
课程设计名称:《单片机原理与接口技术》课程设计
课程设计题目:基于51单片机的出租车计价器
学院名称:信息工程学院
专业:电子信息工程班级: 100415 学号: 27 姓名:夏亮晶
同组人:张先生
评分:教师:邓老师 20XX年 07月 01日
基于51单片机原理出租车计价器的设计
摘要
现在各大中城市出租车行业都已普及自动计价器,所以计价器技术的发展已成定局。而部分小城市尚未普及,但随着城市建设日益加快,象征着城市面貌的出租车行业也将加速发展,计价器的普及也是毫无疑问的,所以未来汽车计价器的市场还是十分有潜力的。
本设计以89S51 单片机为中心,利用信号发生器模拟代替霍尔传感器测距,实现对出租车计价统计,输出采用LM016L液晶显示屏。本电路设计的计价器不但能实现基本的计价,而且还能根据里程或手动来调节单价。通过单片机上的键盘上的按键来执行开始、暂停、复位等功能。步骤如下:首先,程序开始做一些必要的初始化工作,等待键盘输入。然后,启动键K1按下后单片机开始计数传感器传来的计数脉冲,在LM016L液晶显示器显示路程,按下K2显示总费用price 是多少,当路程超过3Km,才开始计算。通过K3、K4,K5、K6,K7、K8改变单价price 个位,十分位,百分位。
关键词:89S51单片机LM016L液晶显示屏计价器
目录
前言
单片机课程设计是单片机技术学习中非常重要的一个环节,是将理论知识和实践能力相统一的一个环节,是真正锻炼学生能力的一个环节。出租车能保证乘客快速,轻松的到达目的地。这些优点受到人们的欢迎。
随着出租车行业的发展,出租车已经是城市交通的重要组成部分,从加强行业管理以及减少司机与乘客的纠纷出发,具有良好性能的计价器对出租车司机和乘客来说都是很必要的。而采用模拟电路和数字电路设计的计价器整体电路的规模较大,用到的器件多,造成故障率高,难调试。而采用单片机进行的设计,相对来说功能强大,用较少的硬件和适当的软件相互配合可以很容易地实现设计要求,且灵活性强,可以通过软件编程来完成更多的附加功能。本设计采用AT89C52单片机,辅以按键,实现对出租车的多功能的计价设计,输出采用LM016L液晶显示屏。本电路设计的计价器不但能实现基本的计价,而且还能根据里程或手动来调节单价。
要将出租车计价系统产品化,应该根据客户不同的需求进行不同的设计,应该在程序中增加一些可以人为改变的参数,以便客户根据不同的需要随时调节单价以及计价方式。因此,研究出租车计价器及扩大其应用,有着非常现实的意义。
第一章出租车计价系统的设计要求与设计方案
1.1出租车计价器设计要求
设计一个出租车自动计费器,计费包括起步价、行车里程计费、等待时间计费三部分,用LM016L液晶显示总金额,运行时间,暂停时间,起步价为6元,3Km之内起步价计费,超过3Km,每一公里增加1.6元(即1KM增加1.6元),用液晶显示总里程,同时用液晶显示总金额,单价。
①、计费功能
费用的计算是按行驶里程收费。设起步价为6元。
1、当里程<3km时,按起价计算费用
2、当里程>3km时,每公里按1.6元计费
3、S1为启动路程按钮、S2为启动计价按钮、S3~S8为调整计费按钮、
②、显示功能
1、显示行驶里程:用三位数字显示,显示方式为“XX.X”,单位为km。计
程范围0-999.9km,精确到0.01km。
2.显示计费单价X.XX,精确到0.01元。
3、显示总费用:用三位数字显示,显示方式为“XXXX.XX”,单位为元。计
价范围0-9999.99元,精确到0.01元。
1.2系统主要功能
本出租车自动计费,上电后显示最初的起步价,里程计费单价,计费单价,通过按键可以调节起步价,里程计费单价。同时具有运行,暂停,停止等状态,具有累加功能。出租车停止后能够显示行驶的总费用。
1.3方案论证与比较
方案一:采用数字电子技术,利用555定时芯片构成多谐振荡器,或采用外围的晶振电路作为时钟脉冲信号,采用计数芯片对脉冲尽心脉冲的计数和分频,最后通过译码电路对数据进行译码,将译码所得的数据送给数码管显示,一下是该方案的流程框图,方案一如图1-1所示:
图1-1方案一
案二:采用EDA技术,根据层次化设计理论,该设计问题自顶向下可分为分频模块,控制模块计量模块、译码和动态扫描显示模块,其系统框图如图1-2所示:
图1-2方案二
方案三:采用MCU技术,通过单片机作为主控器,利用1602字符液晶作为显示电路,采用外部晶振作为时钟脉冲,通过按键可以方便调节,以下是方案三的系统流程图,本方案主要是必须对于数字电路比较熟悉,成本又不高。方案图如图1-3所示:
图1-3方案三
方案总结:通过各个方案的比较,本次采用方案三,不但控制简单,而且成本低廉,设计电路简单。
第二章出租车计价系统的硬件设计
2.1振荡电路
单片机内部有一个高增益、反相放大器,其输入端为芯片引脚XTAL1,其输出端为引脚XTAL2。通过这两个引脚在芯片外并接石英晶体振荡器和两只电容(电容和一般取33pF)。这样就构成一个稳定的自激振荡器。
振荡电路脉冲经过二分频后作为系统的时钟信号,再在二分频的基础上三分频产生ALE信号,此时得到的信号时机器周期信号。振荡电路如图2-1所示:
图2-1振荡电路
2.2复位电路设计
复位操作有两种基本形式:一种是上电复位,另一种是按键复位。按键复位具有上电复位功能外,若要复位,只要按图中的RESET键,电源VCC经电阻R1、R2分压,在RESET端产生一个复位高电平。上电复位电路要求接通电源后,通过外部电容充电来实现单片机自动复位操作。上电瞬间RESET引脚获得高电平,随着电容的充电,RERST引脚的高电平将逐渐下降。RERST引脚的高电平只要能保持足够的时间(2个机器周期),单片机就可以进行复位操作。按键复位电路图如图2-2所示。
图2-2 AT89C51引脚配置
2.3键盘接口电路
独立式键盘:独立式键盘中,每个按键占用一根I/O口线,每个按键电路相对独立。I/O口通过按键与地相连,I/O口有上拉电阻,无键按下时,引脚端为高电平,有键按下时,引脚电平被拉低。I/O口内部有上拉电阻时,外部可不接上拉电阻。键盘接口电路如图2-3所示:
图2-3键盘接口电路
2.4显示电路
对于现实电路我们可以采用数码管,也可以采用液晶显示,液晶又分字符型和点阵型,我们使用的液晶是字符型液晶,并且带字符库的,不需要查找代码。英文字符就可。液晶电路使用时,如果发现液晶不亮可以调节连接液晶的点位器,改变液晶的亮度。显示电路如图2-4所示:
图2-4 数码管封装图及数据线与数码管管脚关系
2.5路程测量部分
出租车中需要一个能准确获得车轮转动即路量信号的装置,以得到标准的脉冲信号送入单片机的定时/ 计数器T1 即P3. 5 引脚,利用单片机的T1 的计数功能完成100次的计数后产生一中断来完成路程的测量。(设车轮周长为1 m ,则霍尔传感器每产生100 个脉冲便表示车已行程0. 1 km ,根据际情况在程序中进行设置) 。汽车联轴器按圆周间隔嵌入磁钢,用霍传感器集成芯片A44E 测并输出脉冲,其工作原理如图4 所示,霍尔传感器集成芯片A44E 有信号转换、电压放大、等功能,为增加其抗干扰的能力,经过74L S14 对信号整形后再通过光偶送入P3. 5 引脚。
图2-5路程测量电路
2.6单片机各引脚功能说明
AT89S52电路图如图2-6所示:
VCC:供电电压。GND:接地。P0口:P0口为一个8位漏级开路双向I/O口,每脚可吸收8TTL门流。当P1口的管脚第一次写1时,被定义为高阻输入。P0能够用于外部程序数据存储器,它可以被定义为数据/地址的第八位。在FIASH编程时,P0 口作为原码输入口,当FIASH进行。校验时,P0输出原码,此时P0外部必须被拉高。
图2-6 AT89S52
P1口:P1口是一个内部提供上拉电阻的8位双向I/O口,P1口缓冲器能接收输出4TTL门电流。
P1口管脚写入1后,被内部上拉为高,可用作输入,P1口被外部下拉为低电平时,将输出电流,这是由于内部上拉的缘故。在FLASH编程和校验时,P1口作为第八位地址接收。
P2口:P2口为一个内部上拉电阻的8位双向I/O口,P2口缓冲器可接收,输出4个TTL门电流,当P2口被写“1”时,其管脚被内部上拉电阻拉高,且作为输入。并因此作为输入时,P2口的管脚被外部拉低,将输出电流。这是由于内部上拉的缘故。P2口当用于外部程序存储器或16位地址外部数据存储器进行存取时,P2口输出地址的高八位。在给出地址“1”时,它利用内部上拉优势,当对外部八位地址数据存储器进行读写时,P2口输出其特殊功能寄存器的内容。P2口在FLASH编程和校验时接收高八位地址信号和控制信号。
P3口:P3口管脚是8个带内部上拉电阻的双向I/O口,可接收输出4个TTL 门电流。当P3口写入“1”后,它们被内部上拉为高电平,并用作输入。作为输入,由于外部下拉为低电平,P3口将输出电流(ILL)这是由于上拉的缘故。P3
口也可作为AT89S52的一些特殊功能口,P3口同时为闪烁编程和编程校验接收一些控制信号。
RST:复位输入。当振荡器复位器件时,要保持RST脚两个机器周期的高电平时间。
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:来自反向振荡器的输出。
2.7 1602液晶的简介
字符型液晶1602主要技术参数如表2-1所示:
控制器接口说明(HD44780及兼容芯片)
1、基本操作时序
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=数据输出:无
E=高脉冲
注:对控制器进行读写操作之前,都必须进行读写检测,确保STA7为0 RAM地址映射图
控制器内部带有80*8位的RAM缓冲区,对应关系如下图2-5所示:
控制器内部没有一个数据地址指针,用户可通过它们来访问内部的全部80字节RAM。
第三章出租车计价系统的软件设计
3.1系统主程序
在主程序模块中,需要完成对各参量和接口的初始化、出租车起价和单价的初始化等工作。另外,在主程序模块中还需要设置修改单价的程序。
然后将总金额、里程和单价送数码管显示出来。程序流程如图所示。
3.2里程计数子程序
当汽车运行起来时,就启动计价,根据里程寄存器中的内容计算和判断行驶里程是否已超过起步价公里数。若已超过,则根据里程值、每公里的单价数和起步价数来计算出当前的总金额,并将结果输出在显示屏上。
3.3单价设置子程序
设置单价时,按下S3键,此时按下S2起步价加一元,按下S4起步价减一元。按下S1键程序跳回等待运行阶段。
第四章设计体会与小结
经过这些天有关于出租车计价器的课程设计,使我对单片机的应用有了更深的了解。在课程设计的过程中,还是碰到了许多的问题。比如,对于数码管动态扫描显示、数码管的闪烁和键盘的延时防抖的综合编程不能较好地解决;对于一些相关的应用软件没能熟练掌握。通过这几天晚上的苦想和反复调试,最终还是把问题解决了。
通过这次课程设计,我最大的收获就是自己的动手能力和独立解决问题的能力得到了很大的提高,也充分体会到了自己设计东西的乐趣、学会查阅资料和对别人的东西融会变通的重要性,也明白了很多知识光靠趴在书本上学是学不到其中的精髓的,必须亲自去试着实践,亲自去经历才能对它们真正的掌握。
最大的收获是更清晰了如何有条理的编程。第一个就是流程图,原来不以为然的事现在觉得非常的有必要。第二就是编程顺序,要写一个功能很复杂的程序首先写那些自己可以很快完成的较简单的内容,比如调单价时的闪烁,那么就可以开始只写调一位单价,然后再加入程序可以调两位单价,再然后加入闪烁功能,这样既可以使编程变得更有条理,而且对心态也是很有帮助的。一步一步的完成相应的要求会使自己的心情倍感舒爽而不是一直未能达到要求时的迷茫。
凡事都要自己去动下手,去实践一下,遇到困难,永远不要沮丧气馁。在动手的过程中,不仅能增强实践能力,而且在理论上可以有更深的认识;这次设计给了我极大的鼓舞和信心,相信在以后的学习中可以通过不断的摸索和实践来提高其他方面的知识。
参考文献
1.李群芳、张士军、黄建.《单片微型计算机与接口技术》(第三版).电子工
业出版社,20XX.
2.张鑫、华臻、陈书谦.《单片机原理及应用》[M].电子工业出版社,20XX.
3.丁元杰、吴大伟.《单片微机实题集与实验指导书》[M].机械工业出版社,
20XX.
4.李群芳,肖看.单片机原理接口与应用.北京:清华大学出版社,20XX.
5.张迎新.单片微型计算机原理、应用及接口技术.北京:国防工业出版社,
1999.
6.高峰.单片微型应用系统设计及实用技术.北京:机械工业出版社,20XX.
附录
源程序
#include "main.h"
#include "lcd1602.h"
uchar number1[16] = "D . km P:1.60";
uchar number2[16] = "Price: $";
ulong dis = 0;
ulong price = 600;
uint perk = 160;
uchar state = 0;
uchar choice = 0;
/*----------------------------------------------------- 函数名称:Delay()
函数功能:延时t ms
入口参数:t
出口参数:无
------------------------------------------------------*/ void Delay(uchar t)
{
uchar x,y;
for(x=t; x>0; x--)
for(y=110; y>0; y--);
}
/*----------------------------------------------------- 函数名称:Display()
函数功能:显示路程和单价信息
入口参数:路程X,和单价 P
出口参数:无
------------------------------------------------------*/ void Display(ulong x, uint p)
{
number1[1] = x/10000%10 + '0';
number1[2] = x/1000%10 + '0';
number1[3] = x/100%10 + '0';
number1[5] = x/10%10 + '0';
number1[6] = x%10 + '0';
number1[12] = p/100%10 + '0';
number1[14] = p/10%10 + '0';
number1[15] = p%10 + '0';
if(number1[1] == '0')
{
number1[1] = ' ';
if(number1[2] == '0')
{
number1[2] = ' ';
}
}
Print(0x80,&number1);
}
/*----------------------------------------------------- 函数名称:Show_Price()
函数功能:显示最后的价格
入口参数:单价 temp 全局变量 dis
出口参数:无
------------------------------------------------------*/ void Show_Price(ulong temp)
{
ulong Result = 0;
float value = 1.0;
if(dis <= 300)
Result = price;
else
{
Result = temp*(dis - 300);
value = Result/100 + 0.5;
Result = (ulong)value;
Result += price;
}
number2[8] = Result/100000%10 + '0';
number2[9] = Result/10000%10 + '0';
number2[10] = Result/1000%10 + '0';
number2[11] = Result/100%10 + '0';
number2[12] = '.';
number2[13] = Result/10%10 + '0';
number2[14] = Result%10 + '0';
if(number2[8] == '0')
{
number2[8] = ' ';
if(number2[9] == '0')
{
number2[9] = ' ';
if(number2[10] == '0')
number2[10] = ' ';
}
}
Print(0xc0,&number2);
}
/*----------------------------------------------------- 函数名称:Key_Scan()
函数功能:通过按键设定要的参数数值
入口参数:无
出口参数:无
------------------------------------------------------*/ void Key_Scan(void)
{
if(key1 == 0)
{
Delay(2);
if(key1 == 0)
{
while(!key1);
state ++;
if(state == 3)
state = 0;
}
}
if(key2 == 0)
{
Delay(2);
if(key2 == 0)
{
while(!key2);
choice ++;
if(choice == 2)
choice = 0;
}
}
if(key3 == 0) //参数的百位加 +1
{
Delay(2);
if(key3 == 0)
{
while(!key3);
switch(choice)