基于51单片机出租车计费设计

基于51单片机出租车计费设计

(仿真+程序+原理图+设计报告)

功能介绍

具体功能:

1.当无乘客时液晶可以显示时间(年月日时分秒),时间可以按键设置。

2.当有乘客时电机工作,可以通过按键开始计费系统工作。

3.可以切换白天和夜晚收费标准,可以按照分钟或公里收费切换。

4.可以修改起步价、超过起价费每公里或分钟收费、白天和夜晚收费标准。

​演示视频:

基于51单片机出租车计费设计 

//出租车计价器
//宏定义
#define uchar unsigned char
#define uint unsigned int 

//头函数声明
#include <reg52.h>
#include "Lcd.h"
#include "Data.h"
#include "DS1302.h"
#include "AT24C02.h"


//键盘定义
sbit K1=P3^4;	//模式切换
sbit K2=P3^6;	//减按键
sbit K3=P3^5;	//加按键
sbit K4=P3^7;	//万年历模式时:设置时间信息。计价器模式时:设置单价

//模式0时钟 1时钟调整			   			
uchar Mode=0;
//时钟屏幕调整
uchar Wei=0;
uchar SS=0;
//价格调整
uchar JGWei=0;

//计价器参数
uint Day=0;
uint Night=0;
uint DanJia=0;
uint DJ_min=0;
uint  ZJ=0;
unsigned long  GL=0;
uint  Time=0;
uint count=0;
uchar m=0;
//白天/晚上
uchar DN=0;
//公里/时间
uchar GT=0;

//初始化函数
void InitTimer0();
//写初值
void SETS();
//读初值
void READS();

//主函数
void main()
{
	//初始化
	Ds1302_Init();
	Init_LCD();
	initeeprom();
	//SETS();
	//读取初始参数
	READS();
	//定时器初始化
	InitTimer0();
	//循环
	while(1)
	{
		//时钟模式
		if(Mode==0)
		{
			//读时间
			if(Wei==0)
			{
				Ds1302_Read_Time();
				//显示时间
				display_NYR(time_buf1,Wei,0);
			}
		}
		else if(Mode==1)
		{
			if(time_buf1[4]>=23||time_buf1[4]<7)  
			DN=1;
			else
			DN=0;
			//显示计价器信息
			
			display_S(Day,Night,DanJia,ZJ,GL/10,Time,GT,DN);
		}


		if(K4==0)
		{
			delay(100);
			//调时
			if(Mode==0)
			{
				Wei++;
				if(Wei==1)
				{
					SS=1;
				}
				//闪烁
				display_NYR(time_buf1,Wei,SS);
				if(Wei==7)
				{
					Wei=0;
					//保存时间
					Ds1302_Write_Time();
					Init_LCD();
				}
			}
			else if(Mode==1)
			{
				JGWei++;
				if(JGWei==1)
				{
					Mode=2;
					//显示计价器价格
					Init_LCD_JGTZ();
					display_D(Day,Night,DanJia,JGWei,DJ_min);
				}
			}
			else if(Mode==2)
			{	
				JGWei++;	
				display_D(Day,Night,DanJia,JGWei,DJ_min);
				if(JGWei==5)
				{
					Mode=1;
					JGWei=0;
					//参数初始化
					//保存
					SETS();
					//读初值
					READS();
	
					ZJ=0;
					GL=0;
					Time=0;
					//开启定时器
					TR0=1;
					//显示计价器
					Init_LCD_JJQ();
				}
			}
			while(K4==0);
		}
		//+
		if(K3==0)
		{
			delay(100);
			//调时
			if(Mode==0)
			{
				//年
				if(Wei==1)
				{
					time_buf1[1]++;
					if(time_buf1[1]>=100)
						time_buf1[1]=0;
				}
				//月
				else if(Wei==2)
				{
					time_buf1[2]++;
					if(time_buf1[2]>=13)
						time_buf1[2]=1;
				}
				//日
				else if(Wei==3)
				{
					time_buf1[3]++;
					if(time_buf1[3]>=YDay(time_buf1[1],time_buf1[2])+1)
						time_buf1[3]=1;
				}	
				//时
				else if(Wei==4)
				{
					time_buf1[4]++;
					if(time_buf1[4]>=24)
						time_buf1[4]=0;
				}	
				//分
				else if(Wei==5)
				{
					time_buf1[5]++;
					if(time_buf1[5]>=60)
						time_buf1[5]=0;
				}
				//秒
				else if(Wei==6)
				{
					time_buf1[6]++;
					if(time_buf1[6]>=60)
						time_buf1[6]=0;
				}
				//显示
				if(Wei!=0)
					display_NYR(time_buf1,Wei,SS);			
			}
			//调价
			else if(Mode==2)
			{
				//单价
				if(JGWei==1)
				{
					DanJia++;
					if(DanJia>999)
					{
						DanJia=1;
					}
				}
				//等待时间单价
				else if(JGWei==2)
				{
					DJ_min++;
					if(DJ_min>999)
					{
						DJ_min=1;
					}
				}
				//夜间
				else if(JGWei==3)
				{
					Night++;
					if(Night>999)
					{
						Night=1;
					}
				}
				//白天
				else if(JGWei==4)
				{
					Day++;
					if(Day>999)
					{
						Day=1;
					}
				}
				display_D(Day,Night,DanJia,JGWei,DJ_min);
			}

			while(K3==0);
		}

		//-
		if(K2==0)
		{
			delay(100);
			//调时
			if(Mode==0)
			{
				//年
				if(Wei==1)
				{
					time_buf1[1]--;
					if(time_buf1[1]<0)
						time_buf1[1]=99;
				}
				//月
				else if(Wei==2)
				{
					time_buf1[2]--;
					if(time_buf1[2]<=0)
						time_buf1[2]=12;
				}
				//日
				else if(Wei==3)
				{
					time_buf1[3]--;
					if(time_buf1[3]<=0)
						time_buf1[3]=YDay(time_buf1[1],time_buf1[2]);
				}	
				//时
				else if(Wei==4)
				{
					time_buf1[4]--;
					if(time_buf1[4]<0)
						time_buf1[4]=23;
				}	
				//分
				else if(Wei==5)
				{
					time_buf1[5]--;
					if(time_buf1[5]<0)
						time_buf1[5]=59;
				}
				//秒
				else if(Wei==6)
				{
					time_buf1[6]--;
					if(time_buf1[6]<0)
						time_buf1[6]=59;
				}
				//显示
				if(Wei!=0)
					display_NYR(time_buf1,Wei,SS);			
			}
			//调价
			else if(Mode==2)
			{
				//单价
				if(JGWei==1)
				{
					DanJia--;
					if(DanJia==0)
					{
						DanJia=999;
					}
				}
				//等待时间单价
				else if(JGWei==2)
				{
					DJ_min--;
					if(DJ_min==0)
					{
						DJ_min=999;
					}
				}
				//夜间
				else if(JGWei==3)
				{
					Night--;
					if(Night==0)
					{
						Night=999;
					}
				}
				//白天
				else if(JGWei==4)
				{
					Day--;
					if(Day==0)
					{
						Day=999;
					}
				}
				display_D(Day,Night,DanJia,JGWei,DJ_min);
			}
			while(K2==0);
		}	
		//切换
		if(K1==0)
		{
			delay(100);
			//计价器模式
			if(Mode==1)
			{
				Mode=0;
				ZJ=0;
				GL=0;
				Time=0;
				//开启定时器
				TR0=0;
				EX0=0;
				//显示计价器
				Init_LCD();
			}
			else if(Mode==0)
			{
				Mode=1;
				//参数初始化
				//读初值
				READS();
				ZJ=0;
				GL=0;
				Time=0;
				//开启定时器
				m=0;
				TR0=1;
				EX0=1;
				//显示计价器
				Init_LCD_JJQ();
			}
			while(K1==0);
		}
	}
}

//初始化函数
void InitTimer0(void)
{
    TMOD = 0x01;
    TH0 = 0x3C;
    TL0 = 0xB0;		//10ms
    EA = 1;
    ET0 = 1;
    TR0 = 1;
	IT0=1;	//INT0负跳变触发
	EX0=0;//开外部INTO中断
}

//定时器0中断10ms
void Timer0Interrupt(void) interrupt 1
{
    TH0 = 0x3C;
    TL0 = 0xB0;   //赋初值
	m++;
	if(m>=20)
	{
		m=0;
		if(count>=60)
		{
			GT=0;
			GL=GL+count/10;
			count=0;
		}
		else
		{
			count=0;
			GT=1;
			Time++;	 //时间++
		}
	}
	 //计算钱数
	 //公里数小于3
	 if(GL<=300)
	 {
		if(DN==0)
		{
			if(Time>60)
				ZJ=Day+Time/60*DJ_min;
			else
				ZJ=Day;
		}	
		else
		{
			if(Time>60)
				ZJ=Night+Time/60*DJ_min;
			else
				ZJ=Night;
		}
	 }
	 else
	 {
		if(DN==0)
		{
			if(Time>60)
				ZJ=Day+(GL/10-20)/10*DanJia+Time/60*DJ_min;
			else
				ZJ=Day+(GL/10-20)/10*DanJia;

		}	
		else
		{
			if(Time>60)
				ZJ=Night+(GL/10-20)/10*DanJia+Time/60*DJ_min;
			else
				ZJ=Night+(GL/10-20)/10*DanJia;
		}
	 }
}
void EXINT0() interrupt 0
{
	count++;
}

//读初值
void READS()
{
	uchar SH=0,SL=0;
	uint temp=0;

	delay(10);
	SL=read_add(0x01);
	delay(10);
	SH=read_add(0x02);
	temp=SH;
	temp=temp<<8;
	temp=temp+SL;
	Day=temp;

	delay(10);
	SL=read_add(0x03);
	delay(10);
	SH=read_add(0x04);
	temp=SH;
	temp=temp<<8;
	temp=temp+SL;
	Night=temp;

	delay(10);
	SL=read_add(0x05);
	delay(10);
	SH=read_add(0x06);
	temp=SH;
	temp=temp<<8;
	temp=temp+SL;
	DanJia=temp;

	delay(10);
	SL=read_add(0x07);
	delay(10);
	SH=read_add(0x08);
	temp=SH;
	temp=temp<<8;
	temp=temp+SL;
	DJ_min=temp;
}


//写初值
void SETS()
{
	uchar SH=0,SL=0;
	uint temp=0;

	temp=Day;
	SL=temp&0x00ff;
	SH=temp>>8;
	delay(10);
	write_add(0x01,SL);
	delay(10);
	write_add(0x02,SH);

	temp=Night;
	SL=temp&0x00ff;
	SH=temp>>8;
	delay(10);
	write_add(0x03,SL);
	delay(10);
	write_add(0x04,SH); 

	temp=DanJia;
	SL=temp&0x00ff;
	SH=temp>>8;
	delay(10);
	write_add(0x05,SL);
	delay(10);
	write_add(0x06,SH);

	temp=DJ_min;
	SL=temp&0x00ff;
	SH=temp>>8;
	delay(10);
	write_add(0x07,SL);
	delay(10);
	write_add(0x08,SH);
}

硬件设计

使用元器件:

单片机:AT89C51;

(注意:单片机是通用的,无论51还是52、无论stc还是at都一样,引脚功能都一样。程序也是一样的。)

结构图

流程图:

设计资料

01 仿真图

本设计使用proteus7.8和proteus8.9两个版本设计,向下兼容,无需担心!具体如图!

显示时间

设置计价

按距离计价

按时间计价

02 原理图

本系统原理图采用Altium Designer19设计,具体如图!

03 程序

本设计使用软件keil4和keil5两个版本编程设计,无需担心!具体如图!

04 设计报告

一万六千字设计报告,具体如下!

05 设计资料

        资料获取请关注同名公众号,全部资料包括仿真源文件 、程序(含注释)、AD原理图、参考论文、流程图等。具体内容如下,全网最全! !

资料获取请观看前面演示视频!

点赞分享一起学习成长。

  • 39
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
基于51单片机出租车计费系统设计主要涉及到硬件和软件两个方面。 硬件方面,我们可以使用51单片机作为主控芯片,并通过与计费器、键盘、显示器等硬件设备的连接,实现相应的功能。计费器可以用于记录车辆行驶里程和时间,并通过串口与单片机进行通信;键盘可以用于输入相关操作指令,如设置起步价、按键计费等;显示器可以用于显示计费结果和相关信息。 软件方面,我们可以利用51单片机的编程能力,编写一系列的程序来实现计费系统的功能。首先,我们需要编程实现与计费器的通信,通过串口接收到计费器发送的数据,进行解析和计算。然后,我们可以编写程序实现键盘输入的处理,包括读取按键值、响应相应的功能指令等。此外,还需要编写程序来控制显示器的显示内容,包括计费结果、车辆信息等。 整个计费系统设计思路可以分为以下几个步骤:首先,初始化系统,包括设置起步价、读取计费器的初始状态等。然后,通过键盘输入实现系统的功能选择,如计费开始、计费结束、重置计费等。接下来,根据计费器发送的数据,进行相应的计算,包括累计里程、累计时间、计费金额等。最后,将计费结果显示在显示器上,并实时更新相关信息。 总之,基于51单片机出租车计费系统设计涉及到硬件和软件的协同工作,通过合理的硬件布局和程序编写,可以实现对出租车计费和信息显示等功能。这样的设计不仅可以提高计费的准确性和效率,还能使乘客和司机之间的交流更加便捷。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值