⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.c

📁 用单片机实现出租车计价器的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
//多模块程序编写得I2C程序!!
//实现简单的数字时钟---DS1307
//experience
//判断时刻,读取时钟为bcd码,十六进制
//先存起步价,无一个误差脉冲(100m),否则先判断则有100m误差(一个脉冲)
//比较分段里程,不用公里,而直接比较100m,还可以减少一个除法
//按键切换的问题,标志位在中断服务程序取反!!!!!!!可悲!!!-----------------------
//整个单片机执行时序问题?----计算等待费用时候!!----------------------
//串口问题!!一定是定时器2出现问题 !!!!
//串行口关于两个文件变量定义的问题!!
//IDATA为什么不会抱错呢
//养成良好的编程习惯!!内存分配-----------

#include<reg52.h>
#include<intrins.h>
#include<serial.h>
#include<lcd.h>
#include<IIC.h>
#define uchar unsigned char
#define uint  unsigned int
#define ulong unsigned long

unsigned char idata buf_seri[6];
bit ack_seri;

uchar code table1[16]=" MARTIAN STUDIO "; 
uchar code table2[16]="状态:载客      ";
uchar code table3[16]="状态:空车      ";
    
	
//声明全局变量
	uchar *s ; 	//I2C器件读写单元缓冲区首地址指针
	uchar no;	//读写I2C器件字节数
	uchar sla ;	//I2C器件内部地址,都为写地址
	uchar suba;	//器件内部地址
	uchar bdata flag ;	//位寻址区定义

	uchar bcd_num ;
	
	sbit fg_1s =flag^4;		//1s刷新标志
	sbit fg_1s1=flag^5;	     //1s刷新,计算等待费用

	sbit fg_qibu =flag^7; 
	bit  fg_day_ng;
	bit  fg_100 ;
	bit  fg_wait;
	bit  key_fg;
	bit  fg_on;
	bit  fg_seri;
	uchar buf_key	;	//存按键值
	uchar idata time_temp[4] ; //存实时读取1307系统时间  
	uchar idata date_temp[3] ; //存实时读取1307系统时间
	uchar idata lcd_temp[16] ;  //显示缓冲?	uchar idata  dis_temp[8];
	uchar idata mrd[8]	;	  //接收缓冲区
	uchar idata trd[8]   ;	  //发送缓冲区
//    uchar idata table_shape0[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//字形表0-9
//	uchar idata table_shape1[10]={0xfc,0x60,0xda,0xf2,0x66,0xb6,0xbe,0xe0,0xfe,0xf6};//字形表
	
	uchar idata table_time[7]={0x00,0x00,0x06,0x03,0x08,0x09,0x05};//设置起始时间2005年9月8号8点0分0秒
	uchar buf_sec;	

	uchar idata stack[10]	;	//人工栈
	uchar idata buf_bcd[9]		;	//存放hex to bcd 后的 bcd 最多存放8位
	
	ulong buf_dis ;		//存放里程,四个字节
	ulong buf_pre ;		//存放价格,四个字节 
	ulong pre_dis ;		//存放上次载客里程	
	ulong pre_pre ;		//存放上次载客费用
		
	ulong total_pre;		//存放总营业额
	ulong day_pre	;		//日额

	uint  qibu_day ;	//存白天起步价格,10元转1000
	uint  qibu_ng  ;	//存夜间起步价格,12元转1200

	uint  midd_day	;   //存3-8km价格1.6元转16
	uint  huikong_day  ;	//存>8km价格2.2元转22
	uint  wait_day ;	//等待价格,1.5元转150


	ulong  wait_sec ;	//存等待时间,为精确计算,按照秒算
	uint wait_min ;		//存等待分
	uint wait_second ;	//存等待秒
	
	uchar dis_wmin	;	//载客结束显示等待分钟
	uchar dis_wsec  ;	//载客结束显示等待秒
	
	uchar dec_sec	;	//存20,1s刷新	
	uchar dia		;	//存放直径
	uchar buf_dia	;  //计算速度,定时次数
	uchar extra		;	//加价
	uint buf_sp	;	//存放速度
	uint buf_sp_temp;	

	uchar pu		;	//存脉冲数191----计算里程
	uchar buf_pu 	;	//暂存脉冲数191		
	


	uchar error_type _at_ 0x30 ;  //存放写器件错误代码类型,全局变量


//初始化清零子函数
void clr_ram( uchar * s,uchar no )
{ static uchar i;
  for(i=0;i<no;i++)
	s[i]=0;		
}	


//清除LCD
void clr_lcd( uchar *s,uchar no)
{ static uchar i;
  for(i=0;i<no;i++)
	s[i]=0x20;		
}	


//hex 转 bcd  子程序
//入口参数长整型数据
//出口参数存bcd码缓冲区 
void hextobcd(ulong a ,uchar * s)
{
	static uchar i;
	ulong temp=a;
	for(i=0; temp;i++ )
	{	s[i]=temp%10;
		temp/=10;
	}
	s[i]='\0';
	bcd_num=i;

}



void out_put( uint a)
{
static	idata uchar b[6];	//存bcd码
static	idata uchar c[6];	  //指针
static	uchar j,i;		

	hextobcd(a,b);
	//倒转
	i=bcd_num;
	for(j=0;j<i; j++)
		c[j]=b[i-j-1]+0x30;
		
	for(j=0;j<i;j++)
		b[j]=c[j];
		b[j]='\0';			//结束标志

UartSendString(b);			//UartSendString(c);错误,指针已经被改变

}
	

//初始化函数
void init(void)
{	clr_ram(time_temp,4) ;	//时间存放单元清零
	clr_ram(date_temp,3) ;	//日期存放单元清零
	clr_ram(dis_temp,8) ;	//显示缓冲区清零
	clr_ram(trd,8)		;	//发送缓冲区单元清零
	clr_ram(mrd,8)		;	//接收缓冲区单元清零
	clr_ram(buf_bcd,9)	;	//bcd码缓冲区清零
	clr_ram(stack,10)	;	//清除人工栈

//以下单元清零

    fg_1s =0;	//显示刷新1s未到
	fg_1s1=0;	//计算等待费用1s未到
	fg_wait=0;
	key_fg=0;
	fg_on=0;	
	fg_100=0;
	fg_qibu=1; 		//计算起步价
	fg_day_ng=1;	//day
	buf_sp=0;
	buf_sp_temp=0;
	
	wait_sec=0;
	wait_min=0;
	buf_sp=0;
	dec_sec=20;
	buf_key=0;		//清除按键值
	buf_dis=0;
	buf_pre=0;
	pre_dis=0;
	pre_pre=0;
	total_pre=0;
	day_pre=0;
	buf_sec=table_time[0];


//以下参数可通过与PC机通信
	dia=50;		//存直径
	extra=12;		//夜间加价0.2
	qibu_day=10000;	//起步价格10
	midd_day=160;		//中间价格1.6元/km
	huikong_day=210;	//回空价格2.2元/km
	wait_day=1500;	//等待价格1.5元/min
	pu=buf_pu=191; //计算里程,脉冲数
	buf_dia=dia;
	qibu_ng= qibu_day/10*extra;//起步价格12
	
	
	
	

	

//定时器设置	
	TMOD=0X21;					//设置TO工作方式
	TH0=0X6c;					//设置T0计数初值 65536-37680=0x6cd0;
	TL0=0Xd0;
	ET0=1;						//启动定时中断
	ET1=0;	
//中断设置

	IE0=0 ;
	IE1=0 ;
	IT0=1 ;
	IT1=1 ;
	EX0=1 ;
	EX1=1 ;
	EA=1  ;	
	TR0=1;						//启动定时器
	TR1=1;
	}


//设置时间
void set_time(void)	
{	
 	no=7;	//写入1307七个字节
	suba=0X00;	//器内地址
	sla=0XD0;	//器件地址
   	
	if (  ! ISendStr(sla,suba,table_time,no)  ) 
		  		
			error_type=0x01;	//写时钟错误,代码0x01
		
}


//读取1307系统时间,入口参数为指向字节单元的指针,
//返回1表示读取成功,读取内容存指针所指缓冲区
void rd_time_date(uchar *p_time, uchar *p_date )
{	//读时间	
	no=4;	//读取1307七个字节
	suba=0X00;	//器内地址
	sla=0XD0;	//器件地址
	if ( ! IRcvStr(sla,suba, p_time, no) ) 
		
			error_type=0x02;	//读时钟错误,代码0x02
	  


	




			
	//读日期
	no=3;	//读取1307七个字节
	suba=0X04;	//器内地址
	sla=0XD0;	//器件地址

	if ( ! IRcvStr(sla,suba, p_date, no) ) 
		
			error_type=0x02;	//读时钟错误,代码0x02
}





//车行驶,切换按键,不影响车里程和费用计算
void on_taxi(void)
{
	//根据100m脉冲加1,代表100m	,根据价格计算费用
	if (  fg_100 )
		   	{ 	   buf_dis+=1;	//里程加100m
				 	 fg_100=0;		//清标志
				  
				   //price
					if ( buf_dis<=30 ) buf_pre=buf_pre;
					if(  buf_dis>30 && buf_dis<=80 && fg_day_ng ) buf_pre+=midd_day ;
					if(  buf_dis>30 && buf_dis<=80 && !fg_day_ng ) buf_pre=buf_pre+midd_day/10*extra;
					if(  buf_dis>80 && fg_day_ng ) buf_pre+=huikong_day;
					if(  buf_dis>80 && !fg_day_ng ) buf_pre+=(huikong_day/10*extra);
			}
		
			//等待费用
				if ( buf_sp<=5 && fg_1s1  )
						{   
    					wait_sec+=1;		//等待累加1s
	    				dis_wmin=wait_min= wait_sec/60;
						dis_wsec=wait_second=wait_sec%60;
						 }
//解决了问题,终于发现问题了!!
				if (  wait_min >5  && wait_second==0 &&fg_1s1   ) 
							fg_wait=1;			//类似中断处理内设置标志位
							
		if (  fg_wait )		
			
				   {	 fg_wait=0;
						 if (  fg_day_ng  )		
							buf_pre+=wait_day;
					 	 else
							 buf_pre=buf_pre+(wait_day/10*extra);
					}
							 
		fg_1s1=0;



}


//key10----service
//开始载客
//计算里程和费用(里程费用和等待费用)
void up_taxi(void)
{
	
	  fg_on=1;	

		if ( time_temp[2]<=0x22   && time_temp[2] >=0x6 )
				fg_day_ng=1;
				else fg_day_ng=0;
	
	//判断起步价格  
	if(fg_qibu)
			if ( fg_day_ng )
						buf_pre=qibu_day;
	
				else 
					buf_pre=qibu_ng;
		fg_qibu=0;
	


  

 
	clr_ram(buf_bcd,8);		//清除bcd缓冲区单元
   	hextobcd(buf_dis,buf_bcd);	//转化距离为bcd

 
//显示里程
//显示里程
	lcd_temp[0]=0xc0;
	lcd_temp[1]=0xef;
	lcd_temp[2]=0xb3;
	lcd_temp[3]=0xcc;
	lcd_temp[4]=0xa3;//显示冒号
	lcd_temp[5]=0xba;
		
if ( buf_bcd[3]  )
	 	lcd_temp[6]=buf_bcd[3]+0x30;
			else 	lcd_temp[6]=0x20;
if (  buf_bcd[3]==0 && buf_bcd[2]==0 )   
		lcd_temp[7]=0x20;					
			else	lcd_temp[7]=buf_bcd[2]+0x30;
	
	lcd_temp[8]=buf_bcd[1]+0x30;	

	lcd_temp[9]=0x2e;	//点
	
	  
	lcd_temp[10]=buf_bcd[0]+0x30;
//KM	
	lcd_temp[11]=0x4B;
	lcd_temp[12]=0x4D;
	

  	lcd_dis_mul(16,0x88,lcd_temp);
	clr_lcd(lcd_temp,16);


	clr_ram(buf_bcd,8);			//清除bcd缓冲区单元
	hextobcd(buf_pre,buf_bcd);	//转为费用为bcd
//显示费用
	lcd_temp[0]=0xb7;
	lcd_temp[1]=0xd1;
	lcd_temp[2]=0xd3;
	lcd_temp[3]=0xc3;
	lcd_temp[4]=0xa3;//显示冒号
	lcd_temp[5]=0xba;
		
	
if ( buf_bcd[5]  )
	 	lcd_temp[6]=buf_bcd[5]+0x30;
			else 	lcd_temp[6]=0x20;
if (  buf_bcd[5]==0 && buf_bcd[4]==0 )   
		lcd_temp[7]=0x20;					
			else	lcd_temp[7]=buf_bcd[4]+0x30;
	
	lcd_temp[8]=buf_bcd[3]+0x30;	

	lcd_temp[9]=0x2e;	//点
	
	  
	lcd_temp[10]=buf_bcd[2]+0x30;
	
//显示元
	lcd_temp[11]=0x59;
	lcd_temp[12]=0x00;
	
	lcd_dis_mul(16,0x90,lcd_temp);		
	clr_lcd(lcd_temp,16);
		
	//根据100m脉冲加1,代表100m	,根据价格计算费用
	if (  fg_100 )
		   	{ 	   buf_dis+=1;	//里程加100m
				 	 fg_100=0;		//清标志
				  
				   //price
					if ( buf_dis<=30 ) buf_pre=buf_pre;
					if(  buf_dis>30 && buf_dis<=80 && fg_day_ng ) buf_pre+=midd_day ;
					if(  buf_dis>30 && buf_dis<=80 && !fg_day_ng ) buf_pre=buf_pre+midd_day/10*extra;
					if(  buf_dis>80 && fg_day_ng ) buf_pre+=huikong_day;
					if(  buf_dis>80 && !fg_day_ng ) buf_pre+=(huikong_day/10*extra);
			}
		
			//等待费用
				if ( buf_sp<=5 && fg_1s1  )
						{   
    					wait_sec+=1;		//等待累加1s
	    				dis_wmin=wait_min= wait_sec/60;
						dis_wsec=wait_second=wait_sec%60;
						 }
//解决了问题,终于发现问题了!!
				if (  wait_min >5  && wait_second==0 &&fg_1s1   ) 
							fg_wait=1;			//类似中断处理内设置标志位
							
		if (  fg_wait )		
			
				   {	 fg_wait=0;
						 if (  fg_day_ng  )		
							buf_pre+=wait_day;
					 	 else
							 buf_pre=buf_pre+(wait_day/10*extra);
					}
							 
		fg_1s1=0;


}





//key1-1--service
//将时间存显示缓冲区单元
void dis_time( void )
{
	static uchar temp;
	lcd_temp[0]=0xca;	//汉字
	lcd_temp[1]=0xb1;
	lcd_temp[2]=0xbc;
	lcd_temp[3]=0xe4;
	lcd_temp[4]=0xa3;
	lcd_temp[5]=0xba;
	
	temp=time_temp[2] ;		//小时
	temp>>=4 ;			//循环右移四位
	temp&=0x0f	;		//取高四位
	lcd_temp[6]=temp+0x30;
	temp=time_temp[2] ;		
	temp&=0x0f	;		//取高四?
	lcd_temp[7]=temp+0x30;


	lcd_temp[8]=0xa3;	//冒号
	lcd_temp[9]=0xba;
	

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -