出租车计价器的设计二

出租车计价器的设计

设计内容与要求:

(1) 里程显示为:***.**

(2)能预置起步价与单价:如起步3 公里 6.00元; 1.60.公里。(可通过按键产生公里数,如每按一次为0.1公里,里程数和价格都用数码管显示)


采用矩阵键盘实现

#include<reg51.h>

#define GPIO_DIG P0
#define GPIO_KEY P1

sbit LSA=P2^2;
sbit LSB=P2^3;
sbit LSC=P2^4;

unsigned char code smgduan[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
//0、1、2、3、4、5、6、7、8、9、A、b、C、d、E、F的显示码
unsigned char KeyValue;
//用来存放读取到的键值

typedef unsigned char u8;
typedef unsigned int u16;

u8 KeyState;	//记录按键的状态,0没有,1有
u8 DisplayData[8];	//用来存放要显示的8位数的值
u8 priceFlag;	//设置价格的判断
u8 initPriceFlag; //设置起步价的判断

u16 price, initPrice;//单价,起步价
u16 tempPrice;	//中间变量,为了处理小数点准备的
u16 money; //价钱
u16 keyNum; //里程
//常规延时
void Delay(i)	//延时
{	
	while(i--);
}
//延时10ms
void Delay10ms()   //误差 0us
{
    unsigned char a,b,c;
    for(c=1;c>0;c--)
        for(b=38;b>0;b--)
            for(a=130;a>0;a--);
}
//数码管的显示
void DigDisplay()
{
	u8 i;
	for(i=0;i<8;i++)
	{
		switch(i)
		{
			case 0:LSA=0;LSB=0;LSC=0; break;
			case 1:LSA=1;LSB=0;LSC=0; break;
			case 2:LSA=0;LSB=1;LSC=0; break;
			case 3:LSA=1;LSB=1;LSC=0; break;
			case 4:LSA=0;LSB=0;LSC=1; break;
			case 5:LSA=1;LSB=0;LSC=1; break;
			case 6:LSA=0;LSB=1;LSC=1; break;
			case 7:LSA=1;LSB=1;LSC=1; break;
		}
		GPIO_DIG=DisplayData[i];
		Delay(100);
		GPIO_DIG=0x00;//消隐	
	}
}
//按键扫描
void KeyDown()
{
	u16 a=0;
	GPIO_KEY=0x0f;
	if(GPIO_KEY!=0x0f)
	{
		Delay(1000);
		GPIO_KEY=0x0f;
		if(GPIO_KEY!=0x0f)
		{
			KeyState=1;//有按键按下
			//测试列
			GPIO_KEY=0X0F;
			switch(GPIO_KEY)
			{
				case(0X07):	KeyValue=0;break;
				case(0X0b):	KeyValue=1;break;
				case(0X0d): KeyValue=2;break;
				case(0X0e):	KeyValue=3;break;
			}
			//测试行
			GPIO_KEY=0XF0;
			Delay10ms();
			switch(GPIO_KEY)
			{
				case(0X70):	KeyValue=KeyValue;break;
				case(0Xb0):	KeyValue=KeyValue+4;break;
				case(0Xd0): KeyValue=KeyValue+8;break;
				case(0Xe0):	KeyValue=KeyValue+12;break;
			}
			while((a<50)&&(GPIO_KEY!=0xf0))	 //按键松手检测
			{
				Delay10ms();
				a++;
			}
		}
	}
}
void initTwo()
{
	u8 i;
	for(i=0;i<8;i++)
		DisplayData[i]=0x00;	
}
void init()
{
	initTwo();
	price=0;
	initPrice=0;
	money=0;
	keyNum=0;
}
//输入流动的数据
void setDate()
{	
	tempPrice=tempPrice*10;
	tempPrice=tempPrice+KeyValue;
	DisplayData[3]=DisplayData[2];
	DisplayData[2]=DisplayData[1];
	DisplayData[1]=DisplayData[0];
	DisplayData[0]=smgduan[KeyValue];
}
//小数点的处理
void decimalPoint()
{
	DisplayData[0]=DisplayData[0]|0x80;
	if(priceFlag)	price=tempPrice*100;
	if(initPriceFlag)	initPrice=tempPrice*100;
	tempPrice=0;
}
//确认键
void sureKey()
{
	if(priceFlag)	price=tempPrice+price;
	if(initPriceFlag)	initPrice=tempPrice+initPrice;
	initPriceFlag=0;
    priceFlag=0;
	tempPrice=0;
}
u16 tempNum;
void datapros()
{
	tempPrice=initPrice;
	tempNum=keyNum;
	if(keyNum  <= 30){
			DisplayData[0]=smgduan[tempPrice%10];
			tempPrice=tempPrice/10;
			DisplayData[1]=smgduan[tempPrice%10];
			tempPrice=tempPrice/10;
			DisplayData[2]=smgduan[tempPrice%10]|0x80;
			tempPrice=tempPrice/10;
			DisplayData[3]=smgduan[tempPrice%10];
	}else{
			money=keyNum-30;  
        	money=money*price;
			money=money/10;  
        	money=money+initPrice;  
        	DisplayData[0]=smgduan[money % 10];  
        	money = money / 10;  
        	DisplayData[1]=smgduan[money % 10];  
        	money = money / 10;  
        	DisplayData[2]=smgduan[money % 10]|0x80;  
        	money = money / 10;  
        	if(money)  
        	{  
            	DisplayData[3]=smgduan[money % 10];  
        	}  
	}

	DisplayData[4]=smgduan[tempNum%10];  
    tempNum = tempNum / 10;  
    DisplayData[5]=smgduan[tempNum%10]|0x80;  
    tempNum = tempNum / 10;  
    if(tempNum) DisplayData[6]=smgduan[tempNum%10];  
    tempNum = tempNum / 10;  
    if(tempNum) DisplayData[7]=smgduan[tempNum%10]; 
}

void main(void)
{
	KeyState=0;
	while(1)
	{
		KeyDown();
	 	if(KeyState==1)
		{
			switch(KeyValue)
			{
				case 0:
				case 1:
				case 2:
				case 3:
				case 4:
				case 5:
				case 6:
				case 7:
				case 8:	
				case 9:
				if(initPriceFlag || priceFlag)	setDate();
				break;
				case 10: initPriceFlag=1;	//S11
						 priceFlag=0;
						 break;//选择设置起步价
				case 11: priceFlag=1;		//选额设置价格 S12
						 initPriceFlag=0;	
						 break;
				case 12: sureKey();//确认按键 S13
						 initTwo();
						 break;
				case 13: decimalPoint();	//S14
						 break;	//小数点按键处理
				case 14: init();	break;	//复位 S15
				case 15: keyNum++;	//里程设置
						 datapros();
					     break;
			}
			KeyState=0;
		}
		
		DigDisplay();
	}				
}

版本二

#include<reg51.h>

#define GPIO_DIG P0
#define GPIO_KEY P1

sbit LSA=P2^2;
sbit LSB=P2^3;
sbit LSC=P2^4;

unsigned char code smgduan[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
//0、1、2、3、4、5、6、7、8、9、A、b、C、d、E、F的显示码
unsigned char KeyValue;
//用来存放读取到的键值

typedef unsigned char u8;
typedef unsigned int u16;

u8 KeyState;	//记录按键的状态,0没有,1有
u8 DisplayData[8];	//用来存放要显示的8位数的值
u8 priceFlag;	//设置价格的判断
u8 initPriceFlag; //设置起步价的判断
u8 cadFlag;

u16 price, initPrice;//单价,起步价
u16 tempPrice;	//中间变量,为了处理小数点准备的
u16 money; //价钱
u16 keyNum; //里程
//常规延时
void Delay(i)	//延时
{	
	while(i--);
}
//延时10ms
void Delay10ms()   //误差 0us
{
    unsigned char a,b,c;
    for(c=1;c>0;c--)
        for(b=38;b>0;b--)
            for(a=130;a>0;a--);
}
//数码管的显示
void DigDisplay()
{
	u8 i;
	for(i=0;i<8;i++)
	{
		switch(i)
		{
			case 0:LSA=0;LSB=0;LSC=0; break;
			case 1:LSA=1;LSB=0;LSC=0; break;
			case 2:LSA=0;LSB=1;LSC=0; break;
			case 3:LSA=1;LSB=1;LSC=0; break;
			case 4:LSA=0;LSB=0;LSC=1; break;
			case 5:LSA=1;LSB=0;LSC=1; break;
			case 6:LSA=0;LSB=1;LSC=1; break;
			case 7:LSA=1;LSB=1;LSC=1; break;
		}
		GPIO_DIG=DisplayData[i];
		Delay(100);
		GPIO_DIG=0x00;//消隐	
	}
}
//按键扫描
void KeyDown()
{
	u16 a=0;
	GPIO_KEY=0x0f;
	if(GPIO_KEY!=0x0f)
	{
		Delay(1000);
		GPIO_KEY=0x0f;
		if(GPIO_KEY!=0x0f)
		{
			KeyState=1;//有按键按下
			//测试列
			GPIO_KEY=0X0F;
			switch(GPIO_KEY)
			{
				case(0X07):	KeyValue=0;break;
				case(0X0b):	KeyValue=1;break;
				case(0X0d): KeyValue=2;break;
				case(0X0e):	KeyValue=3;break;
			}
			//测试行
			GPIO_KEY=0XF0;
			Delay10ms();
			switch(GPIO_KEY)
			{
				case(0X70):	KeyValue=KeyValue;break;
				case(0Xb0):	KeyValue=KeyValue+4;break;
				case(0Xd0): KeyValue=KeyValue+8;break;
				case(0Xe0):	KeyValue=KeyValue+12;break;
			}
			while((a<50)&&(GPIO_KEY!=0xf0))	 //按键松手检测
			{
				Delay10ms();
				a++;
			}
		}
	}
}
void initOne()
{
	u8 i;
	for(i=0;i<4;i++)
		DisplayData[i]=smgduan[0];
}
void init()
{
	price=0;
	initPrice=0;
	money=0;
	keyNum=0;
}
void setRad()
{
	u8 i;
	for(i=0;i<8;i++)
		DisplayData[i]=0x00;
}
//输入流动的数据
void setDate()
{	
	tempPrice=tempPrice*10;
	tempPrice=tempPrice+KeyValue;
	DisplayData[3]=DisplayData[2];
	DisplayData[2]=DisplayData[1];
	DisplayData[1]=DisplayData[0];
	DisplayData[0]=smgduan[KeyValue];
}
//小数点的处理
void decimalPoint()
{
	DisplayData[0]=DisplayData[0]|0x80;
	if(priceFlag)	price=tempPrice*100;
	if(initPriceFlag)	initPrice=tempPrice*100;
	tempPrice=0;
}
//确认键
void sureKey()
{
	if(priceFlag)	price=tempPrice+price;
	if(initPriceFlag)	initPrice=tempPrice+initPrice;
	initPriceFlag=0;
    priceFlag=0;
	tempPrice=0;
}
u16 tempNum;
void datapros()
{
	tempPrice=initPrice;
	tempNum=keyNum;
	if(keyNum  <= 30){
			DisplayData[0]=smgduan[tempPrice%10];
			tempPrice=tempPrice/10;
			DisplayData[1]=smgduan[tempPrice%10];
			tempPrice=tempPrice/10;
			DisplayData[2]=smgduan[tempPrice%10]|0x80;
			tempPrice=tempPrice/10;
			if(tempPrice) DisplayData[3]=smgduan[tempPrice%10];
	}else{
			money=keyNum-30;  
        	money=money*price;
			money=money/10;  
        	money=money+initPrice;  
        	DisplayData[0]=smgduan[money % 10];  
        	money = money / 10;  
        	DisplayData[1]=smgduan[money % 10];  
        	money = money / 10;  
        	DisplayData[2]=smgduan[money % 10]|0x80;  
        	money = money / 10;  
        	if(money)  
        	{  
            	DisplayData[3]=smgduan[money % 10];  
        	}  
	}

	DisplayData[4]=smgduan[tempNum%10];  
    tempNum = tempNum / 10;  
    DisplayData[5]=smgduan[tempNum%10]|0x80;  
    tempNum = tempNum / 10;  
    if(tempNum) DisplayData[6]=smgduan[tempNum%10];  
    tempNum = tempNum / 10;  
    if(tempNum) DisplayData[7]=smgduan[tempNum%10]; 
}

void main(void)
{
	KeyState=0;
	while(1)
	{
		KeyDown();
	 	if(KeyState==1)
		{
			switch(KeyValue)
			{
				case 0:
				case 1:
				case 2:
				case 3:
				case 4:
				case 5:
				case 6:
				case 7:
				case 8:	
				case 9:
				if(cadFlag) 
				{
					cadFlag=0;
					setRad();
				}
				if(initPriceFlag || priceFlag)	setDate();
				break;
				case 10: initPriceFlag=1;	//S11
						 priceFlag=0;
						 initOne();
						 cadFlag=1;	
						 break;//选择设置起步价
				case 11: priceFlag=1;		//选额设置价格 S12
						 initPriceFlag=0;
						 initOne();
						 cadFlag=1;	
						 break;
				case 12: sureKey();//确认按键 S13
						 break;
				case 13: decimalPoint();	//S14
						 break;	//小数点按键处理
				case 14: init();
						 setRad();	
						 break;	//复位 S15
				case 15: keyNum++;	//里程设置
						 datapros();
					     break;
			}
			KeyState=0;
		}
		
		DigDisplay();
	}				
}


出租车计价器键盘
0 1 2 3
4 5 6 7
8 9 起步价 单价
确定 小数点 复位 里程

猜你喜欢

转载自blog.csdn.net/m0_37691414/article/details/80667956