出租车计价器

时间:2021-11-06 11:36:32 资料 我要投稿

出租车计价器

南京工业大学

出租车计价器

创新实践报告

(2011 — 2012 学年 第1 学期)

课程名称: 出租车计价器设计 班 级: 电子0805 学 号: 11 姓 名: 吾晓于 指导教师: 包亚萍

2011年 11月

一.出租车计价器概述 1.设计要求:

设计一个出租车计价器,该计价器的计费系统:行程3公里内,起步费为6元; 3公里外以 每公里1.4元计费.

并能显示日期和当前时间,行驶公里数,总费用和暂停计价功能. 设计的主要技术指标 :

①计价范围:0~999.9元 计价分辨率: 0.1元 ②计程范围:0~99公里 计程分辨率: 1.0公里

本电路以SST89E58单片机为中心、附加555定时器构成多谐振荡器,组成信号产生电路来实现里程计数,DS1302构成时钟电路,实现对出租车计价统计,输出采用LCD液晶显示器。本电路设计的计价器不但能实现基本的计价,同时还能作为时钟为司机提供方便。

二.计价器硬件设计

本系统的硬件设计主要包括单片机SST89E58、LCD数据显示部件、555定时器电路、DS1302时钟电路的设计。在硬件设计过程中,充分利用各部件的功能,实现出租车计价器设计。 1. 系统的硬件构成及功能

它由以下几个部件组成:SST89E58单片机、总金额及里程显示、键盘控制,里程计算单元、时钟电路等。

利用单片机丰富的IO端口,及其控制的灵活性,实现基本的里程计价功能和时钟显示功能。

2. 单片机及其引脚说明

SST89E58与ATMEL、PHILIPS、WINBOND等公司的8位标准8051系列单片机完全兼容,工作频率为0~40MHZ,2.7V~5.5V,1K字节内部SRAM,三个高电流驱动端口(每端口16mA),三个16位定时器/计数器,全双工、增强型串口,掉电检测,低功耗。

SST89E58是一个有40

个引脚的芯片,引脚配置和仿真图如下图所示:

其各自引脚功能如下:

Vcc:电源电压。 GND:地。

P0口:P0口是一组8位漏极开路型双向I/O接口,也即地址/数据总线复用口。当访问外部数据存储器或程序存储器时,这组口线分时转换地址和数据总线复用,在访问期间激活内部上拉电阻。在FLASH编程时,P0口接受指令字节,而在程序校验时 ,输出指令字节。

P1口:P1口是一个带内部上拉电阻的8位双向I/O接口,P1的输出缓冲级

可驱动4个TTL逻辑门电路。FLASH编程和程序校验时,P1接收低8位地址。

P2口:P2口是一个带有内部上拉电阻的8位双向I/O口,P2的输出缓冲级可驱动4个TTL逻辑门电路。在访问外部程序存储器或16位地址的外部数据存储器时P2口送高8位地址数据。FLASH编程或校验时,P2亦接收高位地址和其他控制信号。

P3口:P3口是一组带有内部上拉电阻的8位双向I/O接口。P3口输出缓冲级可驱动4个TTL逻辑门电路。

RST:复位输入。

ALE/ PROG:当访问外部数据时,ALE(地址锁存允许)输出脉冲用于锁存地址的低8位字节。

EA/VPP:外部访问允许。

PSEN:程序储存允许。PSEN输出是外部程序存储器的度选通信号。

XTAL1:振荡器反相放大及内部是钟发生器的输入端。 XTAL2:振荡器反相放大器的输出端。

3. 按键单元的.设计

电路共采用了六个按键和一个开关,S1、S2、S3、S4、S5、S6,其功能分别是:S1光标左移,S2光标右移,S3『+』,S4『-』,S5设定时间,S6暂停。开关为控制计价器工作和停止。

4. 555定时器构成多谐振荡器

555 定时器是一种模拟和数字功能相结合的中规模集成器件。一般用双极性工艺制作的称为 555,用 CMOS 工艺制作的称为 7555,除单定时器外,还有对应的双定时器 556/7556。555 定时器的电源电压范围宽,可在 4.5V~16V 工作,7555 可在 3~18V 工作,输出驱动电流约为 200mA,因而其输出可与 TTL、CMOS 或者模拟电路电平兼容。

555构成多谐振荡器,组成信号产生电路

振荡周期: T=0.7(R1+2R2)C

输出高电平时间 T=(R1+R2)Cln2 输出低电平时间T=R2Cln2

输出方波的占空比为D=tPH/T=(R1+R2)/(R1+2R2) R1=R2=47KΩ

f=1/T=1.43/( R1+R2)C=150Hz

5.DS1302时钟电路

DS1302 是美国DALLAS公司推出的一种高性能、低功耗、带RAM的实时时钟电路,它可以对年、月、日、周日、时、分、秒进行计时,具有闰年补偿功能,工作电压为2.5V~5.5V。采用三线接口与CPU进行同步通信,并可采用突发方式一次传送多个字节的时钟信号或RAM数据。

DS1302的引脚排列,其中Vcc1为后备电源,VCC2为主电源。在主电源关闭的情况下,也能保持时钟的连续运行。DS1302由Vcc1或Vcc2两者中的较大者供电。当Vcc2大于

Vcc1+0.2V时,Vcc2给DS1302供电。当Vcc2小于Vcc1时,DS1302由Vcc1供电。X1和X2是振荡源,外接32.768kHz晶振。RST是复位/片选线,通过把RST输入驱动置高电平来启动所有的数据传送。RST输入有两种功能:首先,RST接通控制逻辑,允许地址/命令序列送入移位寄存器;其次,RST提供终止单字节或多字节数据的传送手段。当RST为高电平时,所有的数据传送被初始化,允许对DS1302进行操作。如果在传送过程中RST置为低电平,则会终止此次数据传送,I/O引脚变为高阻态。上电运行时,在Vcc>2.0V之前,RST必须保持低电平。只有在SCLK为低电平时,才能将RST置为高电平。I/O为串行数据输入输出端(双向),后面有详细说明。SCLK为时钟输入端。 下图为DS1302的引脚功能和仿真图:

6.LCD显示器

LM016L 的结构及功能

LM016L 液晶模块采用 HD44780 控制器,hd44780 具有简单而功能较强的指令集,可以实 现字符移动,闪烁等功能。 液晶模块的引脚功能如下: VSS 一般接地 VDD 接电源(+5V)

V0 液晶显示器对比度调整端,接正电源时对比度最弱,接地电源时对比度最高(对比 度过高时会产生"鬼影",使用时可以通过一个 10K 的电位器调整对比度).

RS 为寄存器选择,高电平 1 时选择数据寄存器,低电平 0 时选择指令寄存器.

R/W 为读写信号线,高电平(1)时进行读操作,低电平(0)时进行写操作. E E(或 EN)端为使能(enable)端,下降沿使能. D0—D3 底4位三态, 双向数据总线0-3位 D4—D7 高4位三态, 双向数据总线4-7位

计价器流程图

总原理图

计价器程序

//出租车车计价器 设计

//该模拟程序折合规则:1km-1m,等待30s-1km-1m,1m-1.4元 //底层规则:若脉冲个数/秒 #include #include #include #include

uchar code univalent[2] = {1,40}; 价整数位,[1]-里程单价小数位

//保存单价的数组,[0]-里程单

uchar code time_pos[7] = {4,-1,7,10,4,7,10}; //各时间在液晶上的显示位置

uchar code money_pos[4] = {4,7,4,7}; //计价器价格各位在液晶上的显示位置

bit config_ok = 0; bit state = 0;

(计里程),1-低速(计时间) bit pause = 0; 价,1-暂停计价

uint pulse_count = 0;

//0-未配置完成,1-配置完成 //当前仪表的运行状态,0-全速//计价停止状态位,0-正常计//脉冲计数器

//保存等待计时的变量,单位为

uint pulse_count_tmp = 0;

uint time_count = 0; 秒,10s-1km-1.4元

uint mileage_count_new = 0,mileage_count_old = 0; //保存里程的变量,通过差值计

算里程变化,单位为km,1km-1.4元,

uchar idata time[7] = {0x09,0x1,0x1,0x1,0x0,0x0,0x0}; //保存时间的数组 uint money[2]={6,0}; //保存车费的数组,[0]-整数位,[1]-小数位

uchar first_3_km = 0;

void INT0_init(void); void INT1_init(void); void Delay(uint); void System_init(void);

void Time_Show(uchar time_data[7]);

void Run_Show_Time(uchar time_data[7]); void Money_Show(uint money[2]); void Show_Wait_Time(uint); void Show_Mileage(void);

void Run_BackGround(void);

出现的

void Run_BackGround(void) { WriteChar('/', 3,0); WriteChar(':',10,0); WriteChar(':',13,0); WriteChar('.',3,1);

WriteChar('Y',6,1);

}

void Show_Mileage(void) { WriteDecimal(pulse_count / 200,0,12,1); WriteInt(pulse_count % 200 / 10,0,0,13,1); WriteChar('.',12,1); WriteString("km",14,1);

}

void Show_Wait_Time(uint time_count) { WriteChar('s',15,1); WriteChar(' ', 10,1);

WriteInt(time_count,1,4,11,1);

//运行起来后,将在LCD上一直

void Money_Show(uint money[2]) { WriteDecimal(money[0],0,3,1); WriteDecimal(money[1],1,3,1);

}

void Run_Show_Time(uchar time_data[7]) { WriteInt(BcdToInt(time_data[2]),1,2, 1,0); WriteInt(BcdToInt(time_data[3]),1,2, 4,0); WriteInt(BcdToInt(time_data[4]),1,2, 8,0); WriteInt(BcdToInt(time_data[5]),1,2,11,0); WriteInt(BcdToInt(time_data[6]),1,2,14,0);

}

void Time_Show(uchar time_data[7]) { WriteChar('/',6,0); WriteChar('/',9,0);

WriteChar(':',6,1); WriteChar(':',9,1);

WriteInt(BcdToInt(time_data[0]),1,2, 4,0); WriteInt(BcdToInt(time_data[2]),1,2, 7,0); WriteInt(BcdToInt(time_data[3]),1,2,10,0); WriteInt(BcdToInt(time_data[4]),1,2, 4,1); WriteInt(BcdToInt(time_data[5]),1,2, 7,1); WriteInt(BcdToInt(time_data[6]),1,2,10,1);

}

void System_init(void) { RstLcd(); ClrLcd(); P1 = 0x00; config_ok = 0; Time_Show(time); LcdPos(5,0);

SetCur(3); INT1_init();

while(config_ok == 0); //等待配置时间结束标志

}

SetCur(1);

WriteString("set time over...",0,0); Delay(60000); ClrLcd();

Run_BackGround(); P1= 0xff;

void Delay(uint dtime) { }

uint temp;

for(temp=0;temp

void INT0_init(void) {

EA = 0; IT0 = 1; EX0 = 1; EA = 1;

}

void INT1_init(void) { EA = 0; }

IT1 = 1; EX1 = 1; EA = 1;

void main() {

uchar time_tmp[7],i; System_init();

DS1302_GetData(time);

pulse_count_tmp = pulse_count;

mileage_count_new = mileage_count_old = 0; Money_Show(money); Run_Show_Time(time); Show_Mileage(); while(1)

{

if(config_ok == 0) System_init();

DS1302_GetData(time_tmp);

if(!(P1 & 0x04)) {

P1 &= 0xfe; P1 |= 0x02; pause = 0;

if(time[6] != time_tmp[6]) { }

Run_Show_Time(time_tmp); for(i = 0;i

time[i] = time_tmp[i];

//若设置时间未完成

first_3_km = 0; money[0] = 6; money[1] = 0;

mileage_count_new = mileage_count_old = 0; WriteString(" ",0,1); WriteString(" ",9,1); Money_Show(money); pulse_count = 0; Show_Mileage(); time_count = 0;

}

else if(pause == 0) {

INT0_init();

if(time[6] != time_tmp[6]) {

Run_Show_Time(time_tmp); for(i = 0;i

if(pulse_count - pulse_count_tmp

行驶(计时),即一秒内,脉冲数目的个数变化值若小于10,则判为低速

{

state = 1; P1 &= 0xfe; P1 |= 0x02;

time_count ++;

//等待计时加1

if(time_count % 10 == 0 && first_3_km > 2)//由等待时间换算公

里数,10s折合为1km(1m) {

}

}

money[1] += 40; if(money[1] > 99) { }

money[0] += 1; money[1] %= 100;

money[0] += 1; Money_Show(money);

else if(time_count % 10 == 0 && first_3_km

mileage_count_old = mileage_count_new; Show_Wait_Time(time_count);

//否则则判为全速状

态(计里程)

}

else {

state = 0; P1 &= 0xfd; P1 |= 0x01; time_count = 0;

//全速状态下,把等

待时间清0

}

pulse_count_tmp = pulse_count;

if(state == 0) {

mileage_count_new = pulse_count / 200;

if(mileage_count_new != mileage_count_old && first_3_km > 2) {

Show_Mileage();

for(i = mileage_count_old;i

money[1] += 40; if(money[1] > 99) { }

money[0] += 1; money[1] %= 100;

}

}

}

}

money[0] += 1;

Money_Show(money); }

mileage_count_old = mileage_count_new;

} else if(mileage_count_new != mileage_count_old && first_3_km

first_3_km ++;

mileage_count_old = mileage_count_new; Show_Mileage();

else { }

if(time[6] != time_tmp[6]) { Run_Show_Time(time_tmp); }

for(i = 0;i

static void INT0_ser(void) interrupt 0 { }

pulse_count ++;

static void INT1_ser(void) interrupt 2 {

uchar month_day[12]={31,0,31,30,31,30,31,31,30,31,30,31}; char result; uchar i;

static uchar pos;

//配置时间

if(!(P2 & 0x20) && config_ok == 0) {

for(i = 0;i

if(!(P2 & 0x20) && config_ok == 0) {

//++

//配置到哪一项

result = BcdToInt(time[pos]) + 1;

if((pos == 0 && result == 50) || (pos == 4 && result == 24) || (pos == 5 && result == 60) || (pos == 6 && result == 60)) result = 0; else if(pos == 2 && result == 13)

result = 1; else if(pos == 3) {

month_day[1] = (time[0] % 4 == 0 && time[0] % 100 != 0) || time[0] % if(result == month_day[time[2] - 1] + 1)

result = 1;

400 == 0 ? 29:28;//判断润平年

}

time[pos] = IntToBcd(result);

//--

}

else;

}

else if(!(P2 & 0x40) && config_ok == 0) {

for(i = 0;i

if(!(P2 & 0x40) && config_ok == 0) {

result = BcdToInt(time[pos]) - 1; if((pos == 0 && result == -1)) result = 49; else if(pos == 2 && result == 0) result = 12;

else if(pos == 3) { month_day[1]=(time[0] % 4 == 0 && time[0] % 100 != 0) || time[0] %

400 == 0 ? 29:28;//判断润平年

if(result == 0)

}

result = month_day[time[2] - 1];

else if(pos == 4 && result == -1) result = 23;

else if((pos == 5 || pos == 6) && result == -1) result = 59; else

;

time[pos] = IntToBcd(result);

} }

else if(!(P2 & 0x08) && config_ok == 0)

//NEXT

{ for(i = 0;i

if(!(P2 & 0x08) && config_ok == 0) { pos++; pos %= 7; if(pos == 1)

pos = 2;

} }

else if(!(P2 & 0x10) && config_ok == 0)

{ for(i = 0;i

if(!(P2 & 0x10) && config_ok == 0) { pos--; if(pos == -1) pos = 6; if(pos == 1)

pos = 0;

}

}

else if(!(P2 & 0x80) && config_ok == 0) { for(i = 0;i

DS1302_Reset();

DS1302_SettingData(time);

}

}

else if(!(P2 & 0x80) && config_ok == 1) { for(i = 0;i

if(!(P2 & 0x80) && config_ok == 1) { config_ok = 0;

}

}

else if(!(P1 & 0x08) && config_ok == 1) {

//PREVIOUS

//ENTER

//CONFIG

}

}

for(i = 0;i

if(!(P1 & 0x08) && config_ok == 1) { pause = ~pause; EX0 = 0; }

if(config_ok == 0) { }

WriteInt(BcdToInt(time[pos]),1,2,time_pos[pos],pos > 3 ?1:0 ); LcdPos(time_pos[pos]+1,pos > 3 ?1:0);

【出租车计价器】相关文章:

出租车计价器作弊与预防07-31

出租车计价器抗干扰问题分析07-26

出租车多功能计价器安装与调测07-31

出租车计价器示值误差测量结果的不确定度评定07-26

旧计价器的汽笛响了08-20

计价器外围故障的调修07-08

出租汽车计价器的发展与车载GPS07-06

出租汽车计价器抗干扰硬件设计07-31

出租汽车计价器检定应注意的问题07-06