C51版计算器,矩形键盘实现

2015-10-21 海滨 程序就是一个世界

#include<stdio.h>
#include<stdlib.h>
#include<reg52.h>
#include<intrins.h>
#define N 10
typedef unsigned char uchar;
typedef unsigned int uint;
sbit FMQ =P3^6;
uchar code smg_num[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xBF,0x7f};
uchar code key_code[]={0xee,0xde,0xbe,0x7e,0xed,0xdd,0xbd,0x7d,0xeb,0xdb,0xbb,0x7b,0xe7,0xd7,0xb7,0x77};

uchar _show_num_arr[N]="";
uchar *tmp=_show_num_arr;
uchar len;
uchar i,_tmp_num,_tmp_state,step=0,oper=0;
float a=0,b=0,res=0;
float _show_num=-1.10;


void re_str(uchar str[],uchar len)
{
	uchar i;
	for(i=0;i<len-1;i++)
	{
		str[i]=0;	
	}	
}
void array_push(uchar c,uchar arr[])
{
	
	tmp=arr;
	len=0;
	while(*tmp!='\0')
	{
		//这里还需要处理两个小数点问题
		if(*tmp=='.')
			len--;
		len++;
		tmp++;
	}
	if(len<8)
	{
		*tmp=c;
		tmp++;
		*tmp='\0';
	}	
	
}
float isFloat(float num)
{
	return num-(long int)num;
}

void delay_ms(uint i)
{
	uchar j=30;
	while(i--)
		while(j--);
}
void beep()
{
	uint j=300;
	while(j--)
	{
		FMQ=0;
		delay_ms(1);
		FMQ=1;
		delay_ms(1);	
	}	
}
void init()
{
	_tmp_state=0x7f;
}

void show_num_array()
{
	tmp=_show_num_arr;
	len=0;
	while(*tmp!='\0')
	{
		len++;
		tmp++;	
	}
	tmp--;
	_tmp_state=0x7f; //0111 1111 => 1011 1111 =>1101 1111
	for(i=0;i<len;i++)
	{
		if(*tmp!='.')
		{
			_tmp_num=(*tmp=='-')? 10 : *tmp-48;				
			P0=smg_num[_tmp_num];
		}
		else
		{
			tmp--;
			i++;
			_tmp_num=(*tmp=='-')? 10 : *tmp-48;
			if(i==1 && len==1)
				P0=smg_num[11];
			else
				P0=smg_num[11]&smg_num[_tmp_num];	
		}
		
		P2=_tmp_state;
		delay_ms(1);
		_tmp_state=_cror_(_tmp_state,1);
		tmp--;	
	}	
}

void _num_int_array(long int num)
{
	if(num<=99999999 && num>=-9999999)
	{	
		/*
		获得字符串
		*/
		sprintf(_show_num_arr,"%ld",num);
		tmp=_show_num_arr;	
	}
	else
	{
		//调用警告函数
	}
		
}
void _num_float_array(float num)
{
	if(num<=-1000000.001 && num>=-9999999.999)
	{	
		sprintf(_show_num_arr,"%ld",(long)num);
		tmp=_show_num_arr;	
	}
	else if(num<=-100000.001 && num>=-999999.999)
	{
		sprintf(_show_num_arr,"%-.1f",num);
		tmp=_show_num_arr;
	}
	else if(num<=-10000.001 && num>=-99999.999)
	{
		sprintf(_show_num_arr,"%-.2f",num);
		tmp=_show_num_arr;
	}
	else if(num<=-1000.0001 && num>=-9999.9999)
	{
		sprintf(_show_num_arr,"%-.3f",num);
		tmp=_show_num_arr;
	}
	else if(num<=-100.00001 && num>=-999.99999)
	{
		sprintf(_show_num_arr,"%-.4f",num);
		tmp=_show_num_arr;
	}
	else if(num<=-10.000001 && num>=-99.999999)
	{
		sprintf(_show_num_arr,"%-.5f",num);
		tmp=_show_num_arr;
	}
	else if(num<=-1.000001 && num>=-9.999999)
	{
		sprintf(_show_num_arr,"%-.6f",num);
		tmp=_show_num_arr;
	}
	else if(num<=-0.000001 && num>=-0.999999)
	{
		sprintf(_show_num_arr,"%-.6f",num);
		tmp=_show_num_arr;
	}
	else if(num>=-0.000001 && num<10.000000)
	{
		sprintf(_show_num_arr,"%-.7f",num);
		tmp=_show_num_arr;
	}
	else if(num>=10.000000 && num<100.000000)
	{
		sprintf(_show_num_arr,"%-.6f",num);
		tmp=_show_num_arr;
	}
	else if(num>=100.000000 && num<1000.000000)
	{
		sprintf(_show_num_arr,"%-.5f",num);
		tmp=_show_num_arr;
	}
	else if(num>=1000.000000 && num<10000.000000)
	{
		sprintf(_show_num_arr,"%-.4f",num);
		tmp=_show_num_arr;
	}
	else if(num>=10000.000000 && num<100000.000000)
	{
		sprintf(_show_num_arr,"%-.3f",num);
		tmp=_show_num_arr;
	}
	else if(num>=100000.000000 && num<1000000.000000)
	{
		sprintf(_show_num_arr,"%-.2f",num);
		tmp=_show_num_arr;
	}
	else if(num>=1000000.000000 && num<10000000.000000)
	{
		sprintf(_show_num_arr,"%-.1f",num);
		tmp=_show_num_arr;
	}
	else if(num>=10000000)
	{
		sprintf(_show_num_arr,"%d",(long int)num);
		tmp=_show_num_arr;
	}
	else
	{
		//调用警告函数
	}

	
	while(*tmp!='\0')
	{
		tmp++;	
	}
	tmp--;
	while(*tmp=='0')
	{
		*tmp='\0';
		tmp--;
	}
	
}

void ShowNum(float num)
{
	if(isFloat(num)==0)
	{
		_num_int_array((long int)num);
	}
	else
	{
		_num_float_array(num);
	}
}

void judge_step()
{
	step++;
	if(step==1)
	{
		a=atof((char*)_show_num_arr);
		re_str(_show_num_arr,N);
		P2=0xFF;
	}
	else if(step==2)
	{
		b=atof((char*)_show_num_arr);
		switch(oper)
		{
			case '+':
				res=a+b;
				break;
			case '-':
				res=a-b;
				break;
			case '*':
				res=a*b;
				break;
			case '/':
				res=a/b;
				break;
			default:
				res=b;
				break;
		}
		ShowNum(res);	
	}
}
void refresh()
{
	len=0;
	re_str(_show_num_arr,N);
	P2=0xFF;
	tmp=_show_num_arr;
	oper=0;
	step=0;
	
}
void judge_re(uchar keycode)
{
	// 3 7 11 15
	if(step>=3 && ((((uint)keycode+1)%4)!=0) && (keycode<13))
	{		 
		refresh();
	}
	else if(step>=3 && ((((uint)keycode+1)%4)==0))
	{	
		step=1;
		switch(keycode)
		{
			case 3:
				oper='+';
				break;
			case 7:
				oper='-';
				break;
			case 11:
				oper='*';
				break;
			case 15:
				oper='/';
				break;
		}
		a=b=res;
		re_str(_show_num_arr,N);
		P2=0xFF;
	}
}
uchar keyscan()
{
	uchar scan1,scan2,keycode,j;

	P1=0xf0;
	scan1=P1;
	if((scan1&0xf0)!=0xf0) //判断是否有按键按下
	{
		delay_ms(15);		//延时15ms
		scan1=P1;
		if((scan1&0xf0)!=0xf0)
		{
			P1=0x0f; //线反转法的关键
			scan2=P1;
			keycode=scan1|scan2; //组合成键值码
			//查表得出键值
			for(j=0;j<16;j++)
			{
				if(keycode==key_code[j])
				{
					beep();
					while(P1==scan2);
					return j;
				}
			}
		}
		else
			P1=0xff;//P1口开启写入状态
	}
	return 16;

}


void input()
{
	_tmp_num=keyscan();
	//如果按键是一个数,那么就重新开始,如果是一个运算符 那么就继续走运算

	
	if(_tmp_num!=16)
	{
		judge_re(_tmp_num);	
		switch(_tmp_num)
		{
			
			case 0:
			case 1:
			case 2:
				array_push(_tmp_num+49,_show_num_arr);
				break;
			case 4:	
			case 5:
			case 6:
				array_push(_tmp_num+48,_show_num_arr);
				break;
			case 8:
			case 9:
			case 10:
				array_push(_tmp_num+47,_show_num_arr);
				break;
				

			case 3:
				if(oper==0)
				{
					oper='+';
					judge_step();
				}
				break;
				
			case 7:
				if(oper==0)
				{
					oper='-';
					judge_step();
				}
					
				break;
			case 11:
				if(oper==0)
				{
					oper='*';
					judge_step();
				}		
				break;
			case 12:
				array_push('.',_show_num_arr);
				break;
			case 13:
				array_push('0',_show_num_arr);
				break;
			case 14:
				judge_step();
				step++;
				break;
			case 15:
				if(oper==0)
				{
					oper='/';
					judge_step();
				}	
				break;
			default:
				break;
		}
	}
		
}

void main()
{
	while(1)
	{
		input();
		show_num_array();
	}

}

折腾了4个小时,在一个连续相加上卡了两个点,我也是醉了

目前可以实现计算器的基本功能,清除和退格还没写,待扩充,面向过程编程思想。

标签: C51版科学计算器

评论:

有意思
2015-10-22 09:26
教教我把

发表评论:


Powered by 海滨Blog
sitemap