当前位置:文档之家› 51单片机计算器(包括三角函数指数函数等)

51单片机计算器(包括三角函数指数函数等)

#include "REG51.h"
#include "oled.h"
#include"math.h"
#include"string.h"


#define pi 3.141592654
#define e 2.718281828


#define KeyPort P0

//定义变量
unsigned char code tables[]={0xee,0xde,0xbe,0x7e,0xed,0xdd,0xbd,0x7d,0xeb,
0xdb,0xbb,0x7b,0xe7,0xd7 ,0xb7,0x77};

char code nub[]={'1','2','3','+','4','5','6','-','7','8','9','*','0','.','=','/'};
char temp[105];
char ac[105];
char txt[20];
double ans;
char flg;
unsigned char tmp;
static char table[]={'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'};

unsigned long atof_A( char *sptr);
unsigned long atof_C( char *sptr);
unsigned long arr(int a,int b);
unsigned long crr(int a,int b);
double abst(double nb);
double my_(char str[]);
void num2char(char str[], float number, u8 g, u8 l);
int isdigit(char c);
int strlen( char str[]);
int priority(char c);
float atof( char *sptr);
double cal(char str[],int len);
int keyscan() ;
void DelayUs2x(unsigned char t);
void DelayMs(unsigned char t);

void main(void)
{ //float tt;

// int pre;
double ans_pe[10];
int lens,i,j,nn,count=0,f,cls,as,jisuan,k=0,TO;
OLED_Init(); //初始化OLED
delay_ms(100);
OLED_Clear();
for(i=0;i<10;i++)
ans_pe[i]=0;
while(1) {

/*
nn=keyscan();
if(nn>=0 &&nn<=15)
{

ac[count++]=nub[nn-1];
ac[count]='\0';
}
*/
nn=keyscan();

// pre =count;
//-----------------------输入算式----------------------------------------
if(nn>0 && nn<=36)
{

if(cls==1)
{
OLED_Clear();
cls=0;

}TO=1;
switch(nn)
{
case 1: ac[count++]='1';break; //1
case 2: ac[count++]='2';break; //2
case 3: ac[count++]='3';break; //3
case 4: ac[count++]='+';break; //+
case 5: ac[count++]='s'; ac[count++]='i'; ac[count++]='n';break; //sin
case 6: ac[--count]='\0';OLED_Clear();break; //DEL
case 7: ac[count++]='4';break; //4
case 8: ac[count++]='5';break; //5
case 9: ac[count++]='6';break; //6
case 10: ac[count++]='-';break; //-
case 11: ac[count++]='c'; ac[count++]='o'; ac[count++]='s';break; //cos
case 12: ac[0]='\0';OLED_Clear();break; //rst
case 13: ac[count++]='7';break; //7
case 14: ac[count++]='8';break; //8
case 15: ac[count++]='9';break; //9
case 16: ac[count++]='*';break;

//*
case 17: ac[count++]='t'; ac[count++]='a'; ac[count++]='n';break; //tan
case 18: ac[count++]='l';ac[count++]='n';break; //ln
case 19: ac[count++]='0';break; //0
case 20: ac[count++]='.';break; //.
case 21: ac[count++]='p';ac[count++]='i';break; //pi
case 22: ac[count++]='/';break; //÷
case 23: ac[count++]='a';ac[count++]='s'; ac[count++]='i'; ac[count++]='n';break; //asin
case 24: ac[count++]='l'; ac[count++]='o'; ac[count++]='g';break; //log
case 25: ac[count++]='e';break; //e
case 26: ac[count++]='(';break; //)
case 27: ac[count++]='s';ac[count++]='q'; ac[count++]='r'; ac[count++]='t';break; //√
case 28: ac[count++]='^';break; //^
case 29: ac[count++]='a';ac[count++]='c'; ac[count++]='o'; ac[count++]='s';break; //acos
case 30: ac[count++]='%';break; //%
case 31: ac[count++]='1';ac[count++]='0';ac[count++]='^';break; //10^
case 32: ac[count++]=')';break; //)
case 33: ac[count++]='A';break; //A
case 34: ac[count++]='C';break; //C
case 35: ac[count++]='a';ac[count++]='t'; ac[count++]='a'; ac[count++]='n';break; //atan
case 36: ac[count++]='=';break; //=
default: break;
}
}
ac[count]='\0';
if(ac[count-1]=='A' &&TO)
{
k++;
TO=0;
if(k>10) k=0;
num2char(txt,ans_pe[k],10,5);

for(i=0;i{
OLED_ShowChar(i*6,4,txt[i]); //OLED_ShowString(0,4,txt); );

}

}
if(ac[count-1]=='C'&&T0)
{
TO=0;
k--;
if(k<0) k=9;
num2char(txt,ans_pe[k],10,5);

for(i=0;i{
OLED_ShowChar(i*6,4,txt[i]); //OLED_ShowString(0,4,txt); );

}


}
lens = strlen(ac);
if(ac[count-1]=='=')
jisuan=1;
if(jisuan)
{
// ac[count]='\0';

count=0;
jisuan=0;
// ac[0]='l';ac[1]='o';ac[2]='g';ac[3]='(';ac[4]='e';ac[5]='+';ac[6]='2';ac[7]='*';ac[8]='3';ac[9]='-';ac[10]='4';ac[11]='+';ac[12]='e';ac[13]=')';
// ac[14]='=';ac[15]='\0';
ans=cal(ac,lens);
as=1;
cls=1;

for(i=1;i<10;i++)
ans_pe[i]=ans_pe[i-1];
ans_pe[0]=ans;
}
//-----------------显示答案-----------------------
// ans=456-(double)41*8/6+3*59*0.54;
num2char(txt,ans,10,5);
f=1;
if(as=1)
{
as=0;
for(i=0;iOLED_ShowChar(i*6,6,' ');
}

for(i=0;i{

if(flg=='-' && txt[i+1]!='0')
{
OLED_ShowChar

(i*6,6,'-');
flg='+';
continue;
}

if(txt[i]=='.')
{
if(txt[i-1]=='0')
OLED_ShowChar((i-1)*6,6,'0');
}
if(f==1 && txt[i]=='0')
continue;
else
{
OLED_ShowChar(i*6,6,txt[i]); //OLED_ShowString(0,4,txt); );
f=0;
}

}
//-----------------显示算式-----------------------
for(i=0;i{
j=i/20;
OLED_ShowChar(i*6%120,j,ac[i]);
}
// num2char(txt,lens,8,5);

delay_ms(70);
//
}

}


int isdigit(char c)
{
if(c>='0' && c<='9')
return 1;
else return 0;
}

int strlen( char str[])
{
int len=0;
while(*(str+len)!='\0')
len++;
return len;
}

int priority(char c) {
if(c == '=') return 0;
if(c == '+') return 1;
if(c == '-') return 1;
if(c == '*') return 2;
if(c == '/') return 2;
if(c == '^') return 3;
return 0;
}

double atof( char *sptr)
{
double tem=10.0;
// char ispnum=1;
int flg_p=1;
double ans=0;


while(*sptr!='\0')//寻找小数点之前的数
{
if(*sptr=='.')
{
sptr++;
flg_p=0;// break;
continue;
}
if(*sptr<'0' || *sptr>'9' ) break;

if( flg_p)
ans=ans*10+(*sptr-'0');
else
{
ans=ans+(double)(*sptr-'0')/( double)tem;
tem=tem*10;
}

sptr++;
}

/* while(*sptr!='\0')//寻找小数点之后的数
{
if(*sptr<'0' || *sptr>'9' ) break;
ans=ans+(float)(*sptr-'0')/tem;
tem=tem*10;
sptr++;
}

num2char(txt,ans,12,6);
OLED_ShowString(0,3,txt);
*/
return ans;

}


double cal(char str[],int len)
{
int i;
int numk=0,opj=0;

float num[50];
int left,right;
float a=0,b=0,n=0;
char op[20];
int k,te;;
//int len=4;

for(i=0;i{

k=0;
te=0;
if(str[i]=='e')
num[numk++]=e;
else if(str[i]=='p'&&str[i+1]=='i')
{
num[numk++]=pi;
i++;
}

///////////////////////////////////////////////////////////////////////////////
else if(str[i]=='l'&&str[i+1]=='o'&&str[i+2]=='g')
{ //处理log函数
left = 0;
right = 0;
// left++;
for(k=i+3;k{
if(str[k]=='(')left++;
if(str[k]==')')right++;
temp[te++]=str[k];
if(left == right)
{
left =0;
right=0;
break;
}
}
temp[te]='\0';
num[numk++]=log10(my_(temp));
//printf("%llf , %d %d\n",cal(temp),numk,opj);
i=k;
}
else if(str[i]=='l'&&str[i+1]=='

n')
{ //处理ln函数
left = 0;
right = 0;
// left++;
for(k=i+2;k{
if(str[k]=='(')left++;
if(str[k]==')')right++;
temp[te++]=str[k];
if(left == right)
{
left =0;
right=0;
break;
}
}
temp[te]='\0';
num[numk++]=log(my_(temp));
//printf("%llf , %d %d\n",cal(temp),numk,opj);
i=k;
}
else if(str[i]=='s'&&str[i+1]=='i'&&str[i+2]=='n')
{ //处理sin函数
left = 0;
right = 0;
// left++;
for(k=i+3;k{
if(str[k]=='(')left++;
if(str[k]==')')right++;
temp[te++]=str[k];
if(left == right)
{
left =0;
right=0;
break;
}
}
temp[te]='\0';
num[numk++]=sin(my_(temp));
//printf("%llf , %d %d\n",cal(temp),numk,opj);
i=k;
}
else if(str[i]=='c'&&str[i+1]=='o'&&str[i+2]=='s')
{ //处cos函数
left = 0;
right = 0;
// left++;
for(k=i+3;k{
if(str[k]=='(')left++;
if(str[k]==')')right++;
temp[te++]=str[k];
if(left == right)
{
left =0;
right=0;
break;
}
}
temp[te]='\0';
num[numk++]=cos(my_(temp));
//printf("%llf , %d %d\n",cal(temp),numk,opj);
i=k;
}
else if(str[i]=='t'&&str[i+1]=='a'&&str[i+2]=='n')
{ //处理tan函数
left = 0;
right = 0;
// left++;
for(k=i+3;k{
if(str[k]=='(')left++;
if(str[k]==')')right++;
temp[te++]=str[k];
if(left == right)
{
left =0;
right=0;
break;
}
}
temp[te]='\0';
num[numk++]=tan(my_(temp));
//printf("%llf , %d %d\n",cal(temp),numk,opj);
i=k;
}
else if(str[i]=='s'&&str[i+1]=='q'&&str[i+2]=='r'&&str[i+3]=='t')
{ //处理sqrt函数 (开方)
left = 0;
right = 0;
// left++;
for(k=i+4;k{
if(str[k]=='(')left++;
if(str[k]==')')right++;
temp[te++]=str[k];
if(left == right)
{

left =0;
right=0;
break;
}
}
temp[te]='\0';
num[numk++]=sqrt(my_(temp));
//printf("%llf , %d %d\n",cal(temp),numk,opj);
i=k;
}
else if(str[i]=='a'&&str[i+1]=='s'&&str[i+2]=='i'&&str[i+3]=='n')
{ //处理sqrt函数 (开方)
left = 0;
right = 0;
// left++;
for(k=i+4;k{
if(str[k]=='(')left++;
if(str[k]==')')right++;
temp[te++]=str[k];
if(left == right)
{
left =0;
right=0;
break;
}
}
temp[te]='\0';
num[numk++]=asin(my_(temp));
//printf("%llf , %d %d\n",cal(temp),numk,opj);
i=k;
}
else if(str[i]=='a'&&str[i+1]=='c'&&str[i+2]=='o'&&str[i+3]=='s')
{ //处理sqrt函数 (开方)
left = 0;
right = 0;
// left++;
for(k=i+4;k{
if(str[k]=='(')left++;
if(str[k]==')')right++;
temp[te++]=str[k];
if(left == right)
{
left =0;
right=0;
break;
}
}
temp[te]='\0';
num[numk++]=acos(my_(temp));
//printf("%llf , %d %d\n",cal(temp),numk,opj);
i=k;
}
else if(str[i]=='a'&&str[i+1]=='t'&&str[i+2]=='a'&&str[i+3]=='n')
{ //处理sqrt函数 (开方)
left = 0;
right = 0;
// left++;
for(k=i+4;k{
if(str[k]=='(')left++;
if(str[k]==')')right++;
temp[te++]=str[k];
if(left == right)
{
left =0;
right=0;
break;
}
}
temp[te]='\0';
num[numk++]=atan(my_(temp));
//printf("%llf , %d %d\n",cal(temp),numk,opj);
i=k;
}
///////////////////////////////////////////////////////////////////////////////

else if(isdigit(str[i]))
{
n=atof(&str[i]);
while(i < len && (isdigit(str[i]) || str[i] == '.'))
i++;
i--;
num[numk++]=n;

}
else
{
if(str[i] == '(')
op[opj++]=str[i];
else if(str[i] == ')')
{
while(op[opj-1] != '(')
{
b=num[numk-1];
numk--;
a=num[numk-1];

numk--;
switch(op[opj-1])
{
case '+': num[numk++]=a+b;break;
case '-': num[numk++]=a-b;break;
case '*': num[numk++]=a*b;break;
case '/': num[numk++]=a/b;break;
case '^': num[numk++]=(double)pow(a,b);break;
}
opj--;
}
opj--;
}
else if(opj==0 || priority(str[i]) > priority(op[opj-1]))
op[opj++]=str[i];
else
{
while(opj!=0 && priority(str[i])<= priority(op[opj-1]))
{
b=num[numk-1];
numk--;
a=num[numk-1];
numk--;

switch(op[opj-1])
{
case '+': num[numk++]=a+b;break;
case '-': num[numk++]=a-b;break;
case '*': num[numk++]=a*b;break;
case '/': num[numk++]=a/b;break;
case '^': num[numk++]=pow(a,b);break;
}
opj--;
}
op[opj++]=str[i];
}


}

}
//opj--;

// opj=strlen(str);
// num2char(txt,b,8,5);
// OLED_ShowString(0,2,txt);
return (num[numk-1]);
// numk--;
}
double abst(double nb)
{
if(nb<0) return (-nb);
return nb;
}


void num2char(char str[], double number, u8 g, u8 l)
{
u8 i;
unsigned long te ,te1;
double t2, t3;
t3=number;
if(number<0)
flg='-';
else flg='+';
number=abst(number);

te = (unsigned long)number/1;
te1=te;
for (i = 1; i<=g; i++)
{
if (te==0)
str[g-i] = table[0];
else
str[g-i] = table[te%10];
te = te/10;
}
str[g] = '.';

t2 =t3;//-te1 ;
// t2=0.1234567;
te = 0;
for(i=1; i<=l; i++)
{
te =t2*10;
str[g+i] = table[te%10];
t2 = (double)(t2*10);//-te);
}
str[g+l+1] = '\0';
}


void DelayUs2x(unsigned char t)
{
while(--t);
}

/*------------------------------------------------
mS延时函数,含有输入参数 unsigned char t,无返回值
unsigned char 是定义无符号字符变量,其值的范围是
0~255 这里使用晶振12M,精确延时请使用汇编
------------------------------------------------*/
void DelayMs(unsigned char t)
{
while(t--)
{
//大致延时1mS
DelayUs2x(245);
DelayUs2x(245);
}
}

/*
int keyscan(void)
{
unsigned char i,Val;
KeyPort=0xf0;//高四位

置高,低四位拉低
if(KeyPort!=0xf0)//表示有按键按下
{
DelayMs(10); //去抖
if(KeyPort!=0xf0)
{ //表示有按键按下
KeyPort=0xfe; //检测第一行
if(KeyPort!=0xfe)
{
DelayMs(10); //去抖
Val=KeyPort&0xf0;
Val+=0x0e;
}
KeyPort=0xfd; //检测第二行
if(KeyPort!=0xfd)
{
DelayMs(10); //去抖
Val=KeyPort&0xf0;
Val+=0x0d;
}
KeyPort=0xfb; //检测第三行
if(KeyPort!=0xfb)
{
DelayMs(10); //去抖
Val=KeyPort&0xf0;
Val+=0x0b;
}
KeyPort=0xf7; //检测第四行
if(KeyPort!=0xf7)
{
DelayMs(10); //去抖
Val=KeyPort&0xf0;
Val+=0x07;
}
}

}

for(i=0;i<16;i++)
{
if(Val==tables[i]) //通过查表得出n的值
return i;


}

return(-1);
}
*/

int keyscan()
{
P0=0xfe; //扫描第1行
if(P2!=0xff) //有按键按下
{
tmp = P2;
DelayMs(10); //去抖
if(P2!=0xff) //延时后确定有按键按下
{
switch(tmp)
{
case 0xfe: return 1; //第1行第1个按键按下
case 0xfd: return 2; //第1行第2个按键按下
case 0xfb: return 3; //第1行第3个按键按下
case 0xf7: return 4; //第1行第4个按键按下
case 0xef: return 5; //第1行第5个按键按下
case 0xdf: return 6; //第1行第6个按键按下
// case 0xbf: keynum=7;break; //第1行第7个按键按下
// case 0x7f: keynum=8;break; //第1行第8个按键按下
}

}
}
DelayMs(5); //去抖
P0=0xfd; //扫描第2行
if(P2!=0xff) //有按键按下
{
tmp = P2;
DelayMs(10); //去抖
if(P2!=0xff) //延时后确定有按键按下
{
switch(tmp)
{
case 0xfe: return 7; //第2行第1个按键按下
case 0xfd: return 8; //第2行第2个按键按下
case 0xfb: return 9; //第2行第3个按键按下
case 0xf7: return 10; //第2行第4个按键按下
case 0xef: return 11; //第2行第5个按键按下
case 0xdf: return 12; //第2行第6个按键按下
// case 0xbf: keynum=15;break; //第2行第7个按键按下
// case 0x7f: keynum=16;break; //第2行第8个按键按下
}

}
}
// DelayMs(5); //去抖
P0=0xfb; //扫描第3行
if(P2!=0xff) //有按键按下
{
tmp = P2;
DelayMs(10); //去抖
if(P2!=0xff) //延时后确定有按键按下
{
switch(tmp)
{
case 0xfe: return 13; //第3行第1个按键按下
case 0xfd: return 14; //第3行第2个按键按下
case 0xfb: return 15; //第3行第3个按键按下
case 0xf7: return 16; //第3行第4个按键按下
case 0xef: return 17; //第3行第5个按键按下
case 0xdf: return 18; //第3行第6个按键按


// case 0xbf: keynum=23;break; //第3行第7个按键按下
// case 0x7f: keynum=24;break; //第3行第8个按键按下
}

}
}
//DelayMs(10); //去抖

P0=0xf7; //扫描第4行
if(P2!=0xff) //有按键按下
{
tmp = P2;
DelayMs(10); //去抖
if(P2!=0xff) //延时后确定有按键按下
{
switch(tmp)
{
case 0xfe: return 19; //第4行第1个按键按下
case 0xfd: return 20; //第4行第2个按键按下
case 0xfb: return 21; //第4行第3个按键按下
case 0xf7: return 22; //第4行第4个按键按下
case 0xef: return 23; //第4行第5个按键按下
case 0xdf: return 24; //第4行第6个按键按下
// case 0xbf: keynum=31; //第4行第7个按键按下
// case 0x7f: keynum=32; //第4行第8个按键按下
}

}
}
// DelayMs(10); //去抖

P0=0xef; //扫描第5行
if(P2!=0xff) //有按键按下
{
tmp = P2;
DelayMs(10); //去抖
if(P2!=0xff) //延时后确定有按键按下
{
switch(tmp)
{
case 0xfe: return 25; //第5行第1个按键按下
case 0xfd: return 26; //第5行第2个按键按下
case 0xfb: return 27; //第5行第3个按键按下
case 0xf7: return 28; //第5行第4个按键按下
case 0xef: return 29; //第5行第5个按键按下
case 0xdf: return 30; //第5行第6个按键按下
//case 0xbf: keynum=39;break; //第5行第7个按键按下
// case 0x7f: keynum=40;break; //第5行第8个按键按下
}

}
}
//DelayMs(5); //去抖

P0=0xdf; //扫描第6行
if(P2!=0xff) //有按键按下
{
tmp = P2;
DelayMs(10); //去抖
if(P2!=0xff) //延时后确定有按键按下
{
switch(tmp)
{
case 0xfe: return 31; //第6行第1个按键按下
case 0xfd: return 32; //第6行第2个按键按下
case 0xfb: return 33; //第6行第3个按键按下
case 0xf7: return 34; //第6行第4个按键按下
case 0xef: return 35; //第6行第5个按键按下
case 0xdf: return 36; //第6行第6个按键按下
//case 0xbf: keynum=47;break; //第6行第7个按键按下
// case 0x7f: keynum=48;break; //第6行第8个按键按下
}

}
}
// DelayMs(5); //去抖
return 0;

}

double my_(char str[])
{
int i;
int numk=0,opj=0;

float num[50];
// int left,right;
float a=0,b=0,n=0;
char op[20];
int k,te;
int le = strlen(str);

for(i=0;i{

k=0;
te=0;
if(str[i]=='e')
num[numk++]=e;
else if(str[i]=='p'&&str[i+1]=='i')
{
num[numk++]=pi;
i++;
}



else if(isdigit(str[i]))
{
n=atof(&str[i]);
while(i < le && (isdigit(str[i]) || str[i

] == '.'))
i++;
i--;
num[numk++]=n;

}
else
{
if(str[i] == '(')
op[opj++]=str[i];
else if(str[i] == ')')
{
while(op[opj-1] != '(')
{
b=num[numk-1];
numk--;
a=num[numk-1];
numk--;
switch(op[opj-1])
{
case '+': num[numk++]=a+b;break;
case '-': num[numk++]=a-b;break;
case '*': num[numk++]=a*b;break;
case '/': num[numk++]=a/b;break;
case '^': num[numk++]=pow(a,b);break;
}
opj--;
}
opj--;
}
else if(opj==0 || priority(str[i]) > priority(op[opj-1]))
op[opj++]=str[i];
else
{
while(opj!=0 && priority(str[i])<= priority(op[opj-1]))
{
b=num[numk-1];
numk--;
a=num[numk-1];
numk--;

switch(op[opj-1])
{
case '+': num[numk++]=a+b;break;
case '-': num[numk++]=a-b;break;
case '*': num[numk++]=a*b;break;
case '/': num[numk++]=a/b;break;
case '^': num[numk++]=pow(a,b);break;
}
opj--;
}
op[opj++]=str[i];
}


}

}
//opj--;

// opj=strlen(str);
// num2char(txt,num[numk-1],8,5);
// OLED_ShowString(0,2,txt);
return (num[numk-1]);
// numk--;
}

unsigned long arr(int a,int b) //a>=b
{
unsigned long ans,ans1=1,ans2=1;
int i;
if(afor(i=2;i<=a;i++)
ans1*=i;
for(i=2;i<=a-b;i++)
ans2*=i;
ans = ans1/ans2;
return ans;
}

unsigned long crr(int a,int b) //a>=b
{
unsigned long ans,ans1=1,ans2=1;
int i;
if(afor(i=2;i<=a;i++)
ans1*=i;
for(i=2;i<=a-b;i++)
ans2*=i;
for(i=2;i<=b;i++)
ans2*=i;
ans = ans1/ans2;
return ans;
}

unsigned long atof_A( char *sptr)
{
unsigned long a=0,b=0;
// char ispnum=1;
int flg_p=1;
unsigned long ans;


while(*sptr!='\0')//寻找小数点之前的数
{
if(*sptr=='.')
{
sptr++;
flg_p=0;// break;
continue;
}
if(*sptr<'0' || *sptr>'9' ) continu

e;

if( flg_p)
a=a*10+(*sptr-'0');
else
{
b=b*10+(*sptr-'0');
}

sptr++;
}
ans=arr(a,b);


return ans;

}

unsigned long atof_C( char *sptr)
{
unsigned long a=0,b=0;
// char ispnum=1;
int flg_p=1;
unsigned long ans=0;


while(*sptr!='\0')//寻找小数点之前的数
{
if(*sptr=='.')
{
sptr++;
flg_p=0;// break;
continue;
}
if(*sptr<'0' || *sptr>'9' ) continue;

if( flg_p)
a=a*10+(*sptr-'0');
else
{
b=b*10+(*sptr-'0');
}

sptr++;
}
ans=crr(a,b);


return ans;

}









相关主题
文本预览
相关文档 最新文档