单片机课程设计出租车计价器.docx
《单片机课程设计出租车计价器.docx》由会员分享,可在线阅读,更多相关《单片机课程设计出租车计价器.docx(34页珍藏版)》请在冰豆网上搜索。
![单片机课程设计出租车计价器.docx](https://file1.bdocx.com/fileroot1/2022-12/12/23ad567e-de7b-42a8-9419-918cc07588c6/23ad567e-de7b-42a8-9419-918cc07588c61.gif)
单片机课程设计出租车计价器
基于51单片机原理出租车计价器的设计
摘要
本设计的是一个基于单片机AT89S52的出租车自动计费设计,附有复位电路,时钟电路,键盘电路等。
复位电路是单片机的初始化操作,除了正常的初始化外,为摆脱困境,通过复位电路可以重新开始。
时钟电路采用12MHz的晶振,作为系统的时钟源,具有较高的准确性。
在上电时字符型液晶1602显示最初的起步价,里程收费,等待时间收费三种收费,通过按键可以调整起步价,里程收费,等待时间收费。
通过按键模拟出租车的运行,暂停,停止。
在1602液晶上可以显示运行的时间,运行时暂停的时间,通过计算可以得出总共的费用和总的路程。
在这里主要是以AT89S52单片机为核心控制器,P0口接1602液晶显示模块,P1口接按键的,通过按键输入。
关键词:
单片机AT89C51;AT89S52;1602液晶;出租车计费器;
目录
前言1
第一章出租车计价系统的设计要求与设计方案2
1.1出租车计价器设计要求2
1.2系统主要功能2
1.3方案论证与比较2
第二章出租车计价系统的硬件设计4
2.1振荡电路4
2.2复位电路设计4
2.3键盘接口电路5
2.4显示电路5
2.5路程测量部分6
2.6单片机各引脚功能说明6
2.71602液晶的简介8
第三章出租车计价系统的软件设计10
3.1单片机资源使用10
3.2中断子函数10
3.3判键子函数11
3.4显示子程序11
3.5总程序流程框图13
第四章proteus的简介14
4.1Proteus介绍14
第五章设计体会与小结15
参考文献15
附录16
一.源程序16
二.设计总图2
第一章出租车计价系统的设计要求与设计方案
1.1出租车计价器设计要求
设计一个出租车自动计费器,计费包括起步价、行车里程计费、等待时间计费三部分,用1602液晶显示总金额,运行时间,暂停时间,最大值为99.9元,起步价为5.0元,3Km之内起步价计费,超过3Km,设速度为100m/s,10s增加1.3元(即1KM增加1.3元),等待时间单价为每分钟1.5元,用液晶显示总里程,同时用液晶显示等待时间和运行花费时间。
①、计费功能
费用的计算是按行驶里程收费。
设起步价为5.00元。
1、当里程<3km时,按起价计算费用
2、当里程>3km时,每公里按1.3元计费
3、等待累计时间>2min时,按1.5元/min计费
②、显示功能
1、显示行驶里程:
用四位数字显示,显示方式为“XXXX”,单位为km。
计程范围0-99km,精确到1km。
2、显示等候时间:
用两位数字显示,显示方式为“XX”,单位为min。
计时范围0-59min,精确到1min。
3、显示总费用:
用四位数字显示,显示方式为“XXX.X”,单位为元。
计价范围0-999.9元,精确到0.1元。
1.2系统主要功能
本出租车自动计费,上电后显示最初的起步价,里程计费单价,等待时间计费单价,通过按键可以调节起步价,里程计费单价,等待时间计费单价。
同时具有运行,暂停,停止等状态,可以显示运行的时间,同时可以显示暂停的时间,具有累加功能,暂停和运行时间在暂停和运行前一次的状态上计时。
出租车停止后能够显示行驶的总费用。
1.3方案论证与比较
方案一:
采用数字电子技术,利用555定时芯片构成多谐振荡器,或采用外围的晶振电路作为时钟脉冲信号,采用计数芯片对脉冲尽心脉冲的计数和分频,最后通过译码电路对数据进行译码,将译码所得的数据送给数码管显示,一下是该方案的流程框图,方案一如图1-1所示:
图1-1方案一
案二:
采用EDA技术,根据层次化设计理论,该设计问题自顶向下可分为分频模块,控制模块计量模块、译码和动态扫描显示模块,其系统框图如图1-2所示:
图1-2方案二
方案三:
采用MCU技术,通过单片机作为主控器,利用1602字符液晶作为显示电路,采用外部晶振作为时钟脉冲,通过按键可以方便调节,以下是方案三的系统流程图,本方案主要是必须对于数字电路比较熟悉,成本又不高。
方案图如图1-3所示:
图1-3方案三
方案总结:
通过各个方案的比较,本次采用方案三,不但控制简单,而且成本低廉,设计电路简单。
第二章出租车计价系统的硬件设计
4.1振荡电路
单片机内部有一个高增益、反相放大器,其输入端为芯片引脚XTAL1,其输出端为引脚XTAL2。
通过这两个引脚在芯片外并接石英晶体振荡器和两只电容(电容和一般取33pF)。
这样就构成一个稳定的自激振荡器。
振荡电路脉冲经过二分频后作为系统的时钟信号,再在二分频的基础上三分频产生ALE信号,此时得到的信号时机器周期信号。
振荡电路如图2-1所示:
图2-1振荡电路
4.2复位电路设计
复位操作有两种基本形式:
一种是上电复位,另一种是按键复位。
按键复位具有上电复位功能外,若要复位,只要按图中的RESET键,电源VCC经电阻R1、R2分压,在RESET端产生一个复位高电平。
上电复位电路要求接通电源后,通过外部电容充电来实现单片机自动复位操作。
上电瞬间RESET引脚获得高电平,随着电容的充电,RERST引脚的高电平将逐渐下降。
RERST引脚的高电平只要能保持足够的时间(2个机器周期),单片机就可以进行复位操作。
按键复位电路图如图2-2所示。
图2-2AT89C51引脚配置
4.3键盘接口电路
独立式键盘:
独立式键盘中,每个按键占用一根I/O口线,每个按键电路相对独立。
I/O口通过按键与地相连,I/O口有上拉电阻,无键按下时,引脚端为高电平,有键按下时,引脚电平被拉低。
I/O口内部有上拉电阻时,外部可不接上拉电阻。
键盘接口电路如图2-3所示:
图2-3键盘接口电路
4.4显示电路
对于现实电路我们可以采用数码管,也可以采用液晶显示,液晶又分字符型和点阵型,我们使用的液晶是字符型液晶,并且带字符库的,不需要查找代码。
英文字符就可。
液晶电路使用时,如果发现液晶不亮可以调节连接液晶的点位器,改变液晶的亮度。
显示电路如图2-4所示:
图2-4数码管封装图及数据线与数码管管脚关系
4.5路程测量部分
出租车中需要一个能准确获得车轮转动即路量信号的装置,以得到标准的脉冲信号送入单片机的定时/计数器T1即P3.5引脚,利用单片机的T1的计数功能完成100次的计数后产生一中断来完成路程的测量。
(设车轮周长为1m,则霍尔传感器每产生100个脉冲便表示车已行程0.1km,根据际情况在程序中进行设置)。
汽车联轴器按圆周间隔嵌入磁钢,用霍传感器集成芯片A44E测并输出脉冲,其工作原理如图4所示,霍尔传感器集成芯片A44E有信号转换、电压放大、等功能,为增加其抗干扰的能力,经过74LS14对信号整形后再通过光偶送入P3.5引脚。
图2-5路程测量电路
4.6单片机各引脚功能说明
AT89S52电路图如图2-6所示:
VCC:
供电电压。
GND:
接地。
P0口:
P0口为一个8位漏级开路双向I/O口,每脚可吸收8TTL门流。
当P1口的管脚第一次写1时,被定义为高阻输入。
P0能够用于外部程序数据存储器,它可以被定义为数据/地址的第八位。
在FIASH编程时,P0口作为原码输入口,当FIASH进行图2-6
校验时,P0输出原码,此时P0外部必须被拉高。
图2-6AT89S52
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:
来自反向振荡器的输出。
4.71602液晶的简介
字符型液晶1602主要技术参数如表2-1所示:
显示容量:
16*2个字符
芯片工作电压:
4.5—5.5V
工作电流:
2.0mA(5.0V)
模块最佳工作电压:
5.0V
字符尺寸:
2.95*4.35(W*H)mm
表2-1字符型液晶1602主要技术参数
接口信号说明如表2-2所示:
编号
符号
引脚说明
编号
符号
引脚说明
1
Vss
电源地
9
D2
DataI/O
2
VDD
电源正极
10
D3
DataI/O
3
VL
液晶显示偏压信号
11
D4
DataI/O
4
Rs
数据/命令选择端(H/L)
12
D5
DataI/O
5
R/W
读/写选择端(H/L)
13
D6
DataI/O
6
E
使能信号
14
D7
DataI/O
7
D0
DataI/O
15
BLA
背光源正极
8
D1
DataI/O
16
BLK
背光源负极
表2-21602接口信号说明
控制器接口说明(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=高脉冲
状态字说明如表2-3所示:
STA7
D7
STA6
D6
STA5
D5
STA4
D4
STA3
D3
STA2
D2
STA1
D1
STA0
D0
表2-3状态字说明(a)
STA0--6
当前数据地址指针的数值
STA7
读写操作使能
1:
禁止0:
允许
表2-4状态字说明(b)
注:
对控制器进行读写操作之前,都必须进行读写检测,确保STA7为0
RAM地址映射图
控制器内部带有80*8位的RAM缓冲区,对应关系如下图2-5所示:
表2-5RAM地址映射图LCD16字*2行
00
01
02
03
04
05
06
07
08
09
0A
0B
0C
0D
0E
0F
10
…
27
40
41
42
43
44
45
46
47
48
49
4A
4B
4C
4D
4E
4F
50
…
67
显示模式设置如表2-6所示:
指令码
功能
0
0
1
1
1
0
0
0
设置16*2显示,5*7点阵,8位数据接口
表2-6显示模式设置
显示开关及光标设置如表2-7所示:
指令码
功能
0
0
0
0
1
D
C
B
D=1开显示;D=0关显示
C=1显示光标;C=0不显示光标
B=1光标闪烁;B=0光标不显示
0
0
0
0
0
1
N
S
N=1当读或写一个字符后地址指针加一,且光标加一
N=0当读或写一个字后地址指针减一,且光标减一
S=1当写一个字符后,整屏显示左移(N=1)或右移(N=0),以得到光标不移动而屏幕移动的效果
S=0当写一个字符,整屏显示不移动
表2-7显示开关及光标设置
数据控制
控制器内部没有一个数据地址指针,用户可通过它们来访问内部的全部80字节RAM。
第三章出租车计价系统的软件设计
4.1单片机资源使用
在本次设计中像电路键盘用到了P1口,其中P1.0到P1.4口作为键盘的输
入,直流电机电路的控制线用了P2口线,P3.0、P3.1、P3.2分别为led信号控制脚。
显示电路用到了P0和P2口,P0口为液晶的数据口。
4.2中断子函数
对于中断程序,只要定时器计数满就会产生中断50ms中断一次,共计20次,秒钟加1,秒钟计满再分钟加,当分钟加到99时全部清零。
以下是中断子函数的流程图如图3-1所示:
图3-1中断子程序流程图
4.3判键子函数
对于独立式键盘判键,首先看有键按下不,如果有键按下则延时一会儿,在判断是否真的有键按下,如果确实有键按下,在判键释放,最后执行键功能程序。
判键子函数的流程框图如图3-2所示:
图3-2判键子程序流程图
4.4显示子程序
1602液晶是字符型液晶,它的内部自带字符库,它可以写两行的字符,同时每行可以写40个字符,在写显示程序的时候,我们先写命令,再设定字符显示,最后写数据,在每写一次命令或数据都需要判断液晶是否忙。
液晶显示程序流程图如图3-3所示:
图3-3显示子程序流程图
图3-3液晶显示程序流程图
4.5总程序流程框图
图3-4整体程序流程图
第四章proteus的简介
4.1Proteus介绍
Proteus软件是来自英国Labcenterelectronics公司的EDA工具软件,它组合了高级原理布图、混合模式SPICE仿真,PCB设计以及自动布线来实现一个完整的电子设计系统。
此系统受益于15年来的持续开发,被《电子世界》在其对PCB设计系统的比较文章中评为最好产品—“TheRoutetoPCBCAD”。
Proteus产品系列也包含了我们革命性的VSM技术,用户可以对基于微控制器的设计连同所有的周围电子器件一起仿真。
用户甚至可以实时采用诸如LED/LCD、键盘、RS232终端等动态外设模型来对设计进行交互仿真。
其功能模块:
—个易用而又功能强大的ISIS原理布图工具;PROSPICE混合模型SPICE仿真;ARESPCB设计。
PROSPICE仿真器的一个扩展PROTEUSVSM:
便于包括所有相关的器件的基于微处理器设计的协同仿真。
此外,还可以结合微控制器软件使用动态的键盘,开关,按钮,LEDs甚至LCD显示CPU模型。
支持许多通用的微控制器,如PIC,AVR,HC11以及8051。
最新支持ARM。
交互的装置模型包括:
LED和LCD显示,RS232终端,通用键盘,I2C,SPI器件。
强大的调试工具,包括寄存器和存储器,断点和单步模式。
IARC-SPY和KeiluVision2等开发工具的源层调试。
应用特殊模型的DLL界面-提供有关元件库的全部文件。
附录
一.源程序
#include
#defineucharunsignedchar
#defineuintunsignedint
sbitrw=P2^1;//读或写
sbitrs=P2^0;//
sbiten=P2^2;//读写时能控制端
sbitb=P0^7;//液晶判断忙标志位
voidlcd_init();//
voidwr_com(ucharcommand);//液晶写命令
voidwr_data(uchardata0);//写数据
voidlcd_clear();//液晶清屏
voidlcd_set();//设置液晶的起始位置
voidbusy();//液晶判忙函数
voiddisplay();//显示
voidprintstring(uchar*s);//直接写字符
voiddisplay1();
voidkey1();
sbitK=P1^0;
sbitK1=P1^1;
sbitK2=P1^2;
sbitK3=P1^3;
sbitK4=P1^4;
sbitg=P2^7;
sbitaa=P2^3;
sbitbb=P2^4;
sbitcc=P2^5;
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};//字符1,2,3,,,,,0
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;
voidinit();//
voidchuli();//
voidchuli1();//
voiddelay(uchart);//
voidclear();//
voidset(ucharx);//
voidset1(uchary);//
ucharcommand;//
ucharcount,count1;//
ucharsecond,minite,second1,minite1;//
unsignedinttt,tt1;//
unsignedcharvalue1=50,value2=25,value3=15;//起始价,运行价,等待价
unsignedintmoney;//金额变量
//*******************************************
voidmain()
{
init();
lcd_init();
while
(1)
{
key1();
chuli();
display();
if(jump_in==1)
{
jump_in=0;
lcd_init();
while
(1)
{
key();
chuli1();
display1();
if(jump_out==1)
{
lcd_init();
jump_out=0;
clear();
break;
}
}
}
}
}
//*******************************************
voidclear()//跳出下一次
{
TR0=0;
TR1=0;
money=0;
second=0;
second1=0;
minite=0;
minite1=0;
value1=50;
value2=25;
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;
}
}
//*******************************************
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;
TR0=0;
TR1=0;
}
//*******************************************
voidt0_(void)interrupt1using0//定时器0中断
{
count++;
if(count==20)
{
count=0;
second++;
if(second==60)
{
second=0;
minite++;
if(minite==99)
{
minite=0;
}
}
}
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
dispbuf1[0]=minite/10;
dispbuf1[1]=minite%10;
dispbuf1[2]=second/10;
dispbuf1[3]=second%10;
}
//*******************************************
voidt1_(void)interrupt3using3//定时器1中断
{
count1++;
if(count1==20)
{
count1=0;
second1++;
if(second1==60)
{
second1=0;
minite1++;
if(minite1==99)
{
minite1=0;
}
}
}
TH1=(65536-50000)/256;
TL1=(65536-50000)%256;
dispbuf1[4]=minite1/