基于51单片机的出租车计价器仿真

仿真图:

在这里插入图片描述

芯片/模块的特点:

AT89C52简介:
AT89C52是一款经典的8位单片机,是意法半导体(STMicroelectronics)公司生产的一系列单片机之一。它基于8051内核,并具有许多与其兼容的特性。

AT89C52的主要特点如下:

内部存储器:AT89C52具有8KB的闪存(Flash)存储器,可用于存储用户程序和数据。这些存储器的内容可以通过编程器进行编程和擦除。

RAM存储器:AT89C52配备了256字节的随机存取存储器(RAM),用于暂存数据和程序的变量。

外部扩展性:AT89C52支持多种外部扩展设备的连接,包括外部存储器(如RAM、EEPROM)和外设(如ADC、LCD、UART等),通过外部硬件连接,可以扩展单片机的功能和应用。

通用I/O引脚:AT89C52拥有32个可编程的通用输入/输出引脚,可用于连接外部设备和与其他芯片进行通信。

定时器/计数器:AT89C52内置了3个16位定时器/计数器和一个可编程的串行定时器/计数器。这些计时器/计数器可用于实现定时功能、生成脉冲信号、测量时间间隔等。

串行通信:AT89C52支持串行通信接口,包括UART(串行异步通信)和SPI(串行外设接口),便于与其他设备进行数据通信和交互。

低功耗模式:AT89C52具有多种低功耗模式,如空闲模式和电源下模式,在不需要执行任务的时候可以将CPU进入低功耗状态以节省能量。

宽电源电压范围:AT89C52的工作电压范围通常为4.0V至5.5V,可以满足大多数应用需求。

DS1302特点:
高精度时间计数:DS1302能够提供高精度的实时时钟计数,可以记录年、月、日、星期、小时、分钟和秒等时间信息。它内部集成了晶体振荡器,提供稳定的时钟信号。

低功耗设计:DS1302采用低功耗设计,可以在低功耗模式下运行,有效延长电池寿命。即使在停电情况下,它也能保持时间数据,并通过外部连接电池继续提供计时功能。

串行接口:DS1302通过串行实时时钟接口(SPI)进行通信和控制。使用少数几个引脚,可以与主控器件进行数据交换和时钟同步。

容易集成:DS1302集成了时钟计数和RAM存储器功能,并具有简单的接口和命令,容易与各种微控制器和单片机集成。它不需要复杂的控制信号,可以通过简单的读写命令进行操作。

可编程控制功能:DS1302具有可编程的控制功能,可以设置闹钟、写保护等特殊功能。它还支持多种时间格式的选择,例如24小时制或12小时制。

温度补偿:DS1302内置温度补偿功能,可以校正温度对时钟频率的影响,提高时钟计数的准确性。

高稳定性和抗震动能力:DS1302具有高稳定性和抗震动能力,适用于各种工业和消费类应用场景。

24C02特点:
存储容量:24C02具有2K位的存储容量,即可以存储2千个位数据。它的存储空间被组织成256个字节,每个字节由8个位组成。

串行接口:24C02采用串行接口进行数据读写,与主控器件之间进行通信。它使用两根线路(串行数据线SDA和串行时钟线SCL)进行数据传输,简化了连接和控制电路。

低功耗:24C02在工作时功耗低,适用于电池供电或对功耗要求较高的应用场景。它还具有自动功耗优化功能,可以在闲置状态下自动进入低功耗模式。

多功能保护:24C02具有多种数据保护功能,包括写保护、密钥保护和唯一序列号保护。这些功能可以保护数据的安全性和完整性。

高速读写操作:24C02支持快速的读写操作,具备高达400 kHz的传输速度。它能够快速、准确地读取和写入存储器中的数据。

长寿命和可靠性:24C02采用耐用的封装材料,具有较高的抗震动和抗振动能力。它具备较长的数据保存时间和可靠性,适用于各种工业和消费类应用。

主程序:

//出租车计价器
//宏定义
#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^5;	//模式切换
sbit K2=P3^6;	//减按键
sbit K3=P3^4;	//加按键
sbit K4=P3^3;	//万年历模式时:设置时间信息。计价器模式时:设置单价

//模式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;
		}
	 }
}

设计文件:

链接:https://pan.baidu.com/s/1TD_woHblf6SzS18mnwywvQ?pwd=2dco

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值