基於51微控制器的科學計算器
科學計算器
1.任務
設計製作一個科學計算器。
2. 要求
(1)按數字 0-9 時應發出蜂鳴器聲音,數越大,頻率越高。 (20 分)
(2) 完成任意兩位數(範圍 0-99)的加減乘除運算,結果只需顯示整數部分,但如果結果為負數應顯示負號。 (20 分)
(3) 完成任意兩位數(範圍 0-99)的加減乘除運算, 結果要求有小數部分,顯示為 xxxx.xxxx(小數點前不超過四位,小數點後若多於四位,只需顯示四位),如果結果為負數應顯示負號。 (20 分)
(4) 完成任意三位數(範圍 0-999)的加減乘除運算, 結果只需顯示整數部分,但如果結果為負數應顯示負號。(10 分)
(5) 對任意兩位整數進行開方運算,結果保留 4 位有效數字。(10 分)
(6) 請完成由三個任意二位陣列成,格式為 dpdpd 形式表示式的運算(假定 d表示任意整數, p 表示任意操作符(加減乘除),x 表示單個數字, 則 dpdpd 的可能形式之一為 11/2+3)。
3.程式碼
#include<reg52.h>
#include<intrins.h>
#include<stdio.h>
#include<math.h>
#define uchar unsigned char
#define uint unsigned int
/************蜂鳴器*****************/
sbit beep=P3^7;
/************LCD*********************/
sbit lcden=P3^4;//液晶使能端
sbit lcdrs=P3^5;//液晶資料命令選擇端
/*************按鍵******************/
sbit key1=P1^0;
sbit key2=P1^1;
sbit key3=P1^2;
sbit key4=P1^3;
sbit key5=P1^4;
sbit key6=P1^5;
sbit key7=P1^6;
sbit key8=P1^7;
sbit key9=P2^0;
sbit key10=P2^1;
sbit key11=P2^2;
sbit key12=P2^3;
sbit key13=P2^4;
sbit key14=P2^5;
sbit key15=P2^6;
sbit key16=P2^7;
sbit key17=P3^0;
sbit key18=P3^1;
sbit key19=P3^2;
sbit key20=P3^3;
uchar array[16]={'\0','\0','\0','\0','\0','\0'};// 鍵盤掃描
uchar str[16]={'\0','\0','\0','\0'}; // 主函式轉換
uint idata va1_ge, va1_shi,va1_bai,va1_qian,va1_wan,va2_ge,va2_shi,va2_bai,va3_ge,va3_shi;//獲取運算元
uchar idata operator,operator1 ,operator2;
int idata operator3_int,operator2_int,operator1_int,value_char,value_int,value_int_jueduizhi;//運算結果
float idata value_float;
int idata value_int_ge, value_int_shi, value_int_bai,value_int_qian,value_int_wan,value_int_shiwan,value_int_shiwan; //運算結果的各位
unsigned long int value_int_long;//運算結果
int idata jj=0;//array下標,
/********函式宣告*********/
void key_scan(void);
void delay(uint z);
void write_com(uchar com);
void write_data(uchar date);
void LCD_Init(void);
void beep0(void);
void beep1(void);
void beep2(void);
void beep3(void);
void beep4(void);
void beep5(void);
void beep6(void);
void beep7(void);
void beep8(void);
void beep9(void);
/*************************主函式*****************/
void main(void)
{
int i=0;
LCD_Init();
beep=0;//不響
while(1)
{
key_scan();
/******************************兩位數算數運算****************************/
if(array[5]=='='&&(array[2]=='+'||array[2]=='-'||array[2]=='*'||array[2]=='/'))
{
va1_shi=array[0]-48;
va1_ge=array[1]-48;
operator=array[2];
va2_shi=array[3]-48;
va2_ge=array[4]-48;
operator1_int=va1_shi*10+va1_ge;// 運算元1(十)
operator2_int=va2_shi*10+va2_ge;//運算元2(十)
switch(operator)
{
case '+':
value_int=operator1_int+operator2_int; //value_int(20-198)
if(value_int<=99)
{
value_int_ge= value_int%10;//取出個位數
str[0]=value_int_ge+48;
value_int_shi= value_int/10;//取出十位數
str[1]= value_int_shi+48;
write_data(str[1]);
write_data(str[0]);
}
else if(value_int>=100)
{
value_int_ge= value_int%10;//取出個位數
str[0]=value_int_ge+48;
value_int_shi= value_int/10%10;//取出十位數
str[1]= value_int_shi+48;
value_int_bai=value_int/100;//取出百位數
str[2]= value_int_bai+48;
write_data(str[2]);
write_data(str[1]);
write_data(str[0]);
}
break;
case '-':
value_int=operator1_int-operator2_int; //value_int(-99-99)
if(value_int<0)
{
if(value_int>-10)
{
value_int_jueduizhi=operator2_int-operator1_int;
str[0]=value_int_jueduizhi+48;
write_data('-');
write_data(str[0]);
}
else if(value_int<-10)
{
value_int_jueduizhi=operator2_int-operator1_int;
str[0]=value_int_jueduizhi%10+48;
str[1]=value_int_jueduizhi/10+48;
write_data('-');
write_data(str[1]);
write_data(str[0]);
}
}
else if(value_int==0)
{
write_data('0');
}
else if(value_int>0)
{
if(value_int>10)
{
value_int_ge= value_int%10;//取出個位數
str[6]=value_int_ge+48;
value_int_shi= value_int/10;//取出十位數
str[7]= value_int_shi+48;
write_data(str[7]);
write_data(str[6]);
}
else if(value_int<10)
{
str[8]=value_int+48;
write_data(str[8]);
}
}
break;
case '*':
value_int=operator2_int*operator1_int;
if(value_int<1000)
{
value_int_ge= value_int%10;//取出個位數
str[0]=value_int_ge+48;
value_int_shi= value_int/10%10;//取出十位數
str[1]= value_int_shi+48;
value_int_bai=value_int/100;//取出百位數
str[2]= value_int_bai+48;
write_data(str[2]);
write_data(str[1]);
write_data(str[0]);
}
else if(value_int>=1000)
{
value_int_ge= value_int%10;//取出個位數
str[0]=value_int_ge+48;
value_int_shi= value_int/10%10;//取出十位數
str[1]= value_int_shi+48;
value_int_bai=value_int/100%10;//取出百位數
str[2]= value_int_bai+48;
value_int_qian=value_int/1000;//取出千位數
str[3]= value_int_qian+48;
write_data(str[3]);
write_data(str[2]);
write_data(str[1]);
write_data(str[0]);
}
break;
//兩位數除法運算
case '/': //0.101010-9.9
value_float=operator1_int/((float)operator2_int);
sprintf(str,"%1.4f",value_float);
if(operator1_int==operator2_int)
write_data(str[0]);
else if((str[2]!='0')&&(str[3]=='0')&&(str[4]=='0')&&(str[5]=='0'))
{write_data(str[0]);write_data(str[1]);write_data(str[2]); }
// if((str[2]!='0')&&(str[3]!='0')&&(str[4]=='0')&&(str[5]=='0'))
// {write_data(str[0]);write_data(str[1]);write_data(str[2]);write_data(str[3]); }
//
// if((str[2]!='0')&&(str[3]!='0')&&(str[4]!='0')&&(str[5]=='0'))
// {write_data(str[0]);write_data(str[1]);write_data(str[2]);write_data(str[3]);write_data(str[4]); }
//
else
{write_data(str[0]);write_data(str[1]);write_data(str[2]);write_data(str[3]);write_data(str[4]); write_data(str[5]);}
break;
}
for(i=0;i<=15;i++)
{
array[i]='\0';
}
jj=0;
}
/******************************二進位制轉換********************************************************/
else if((array[1]=='B')&&(array[2]=='='))
{
if(array[0]=='0')
{
write_data('0');
write_data('0');
write_data('0');
write_data('0');
}
if(array[0]=='1')
{
write_data('0');
write_data('0');
write_data('0');
write_data('1');
}
if(array[0]=='2')
{
write_data('0');
write_data('0');
write_data('1');
write_data('0');
}
if(array[0]=='3')
{
write_data('0');
write_data('0');
write_data('1');
write_data('1');
}
if(array[0]=='4')
{
write_data('0');
write_data('1');
write_data('0');
write_data('0');
}
if(array[0]=='5')
{
write_data('0');
write_data('1');
write_data('0');
write_data('1');
}
if(array[0]=='6')
{
write_data('0');
write_data('1');
write_data('1');
write_data('0');
}
if(array[0]=='7')
{
write_data('0');
write_data('1');
write_data('1');
write_data('1');
}
if(array[0]=='8')
{
write_data('1');
write_data('0');
write_data('0');
write_data('0');
}
if(array[0]=='9')
{
write_data('1');
write_data('0');
write_data('0');
write_data('1');
}
for(i=0;i<=15;i++)
{
array[i]='\0';
}
jj=0;
}
/****************************三位數算數運算**********************************************************/
else if((array[7]=='=')&&(array[4]!='.'))
{
va1_bai=array[0]-48; //第一個運算元的百位
va1_shi=array[1]-48;//第一個運算元的十位
va1_ge=array[2]-48;//第一個運算元的個位
operator=array[3];
va2_bai=array[4]-48; //第二個運算元的百位
va2_shi=array[5]-48;//第二個運算元的十位
va2_ge=array[6]-48;//第二個運算元的個位
operator1_int=va1_bai*100+va1_shi*10+va1_ge;
operator2_int= va2_bai*100+va2_shi*10+va2_ge;
switch(operator)
{
case '+':
value_int=operator1_int+operator2_int; //value_int(200-1998)
if(value_int<=999)
{
value_int_ge= value_int%10;//取出個位數
str[0]=value_int_ge+48;
value_int_shi= value_int/10%10;//取出十位數
str[1]= value_int_shi+48;
value_int_bai=value_int/100;//取出百位數
str[2]= value_int_bai+48;
write_data(str[2]);
write_data(str[1]);
write_data(str[0]);
}
else if(value_int>999)
{
value_int_ge= value_int%10;//取出個位數
str[0]=value_int_ge+48;
value_int_shi= value_int/10%10;//取出十位數
str[1]= value_int_shi+48;
value_int_bai=value_int/100%10;//取出百位數
str[2]= value_int_bai+48;
value_int_qian=value_int/1000;//取出千位數
str[3]= value_int_qian+48;
write_data(str[3]);
write_data(str[2]);
write_data(str[1]);
write_data(str[0]);
}
break;
case '*':
value_int_long=operator1_int*operator2_int;//運算元正確 計算結果不正確(14961) 實際998001
value_int_ge=value_int_long%10;//0
str[0]=value_int_ge+48;
value_int_shi=value_int_long/10%10;//5
str[1]=value_int_shi+48;
value_int_bai=value_int_long/100%10;//2
str[2]=value_int_bai+48;
value_int_qian=value_int_long/1000%10; //1
str[3]=value_int_qian+48;
value_int_wan=value_int_long/10000%10;//1
str[4]=value_int_wan+48;
value_int_shiwan=value_int_long/100000;//2
str[5]=value_int_shiwan+48; //0
if(str[5]!='0')
{write_data(str[5]);}
write_data(str[4]);
write_data(str[3]);
write_data(str[2]);
write_data(str[1]);
write_data(str[0]);
break;
case '/':
if((operator1_int==999)&&(operator2_int==100)) write_data('9');
else
{
value_float=operator1_int/(float)operator2_int;
sprintf(str,"%1.2f",value_float);
write_data(str[0]);
}
break;
case '-':
value_int=operator1_int-operator2_int;
if((value_int>=0)&&(value_int<10))
{
str[0]=value_int+48;
write_data(str[0]);
}
else if((value_int>=10)&&(value_int<100))
{
value_int_ge=value_int%10;
str[0]=value_int_ge+48;
value_int_shi=value_int/10;
str[1]=value_int_shi+48;
write_data(str[1]);
write_data(str[0]);
}
else if(value_int>=100)
{
value_int_ge=value_int%10;
str[0]=value_int_ge+48;
value_int_shi=value_int/10%10;
str[1]=value_int_shi+48;
value_int_bai=value_int/100;
str[2]=value_int_bai+48;
write_data(str[2]);
write_data(str[1]);
write_data(str[0]);
}
else if((-10<value_int)&&(value_int<0))
{
value_int_jueduizhi=operator2_int-operator1_int;
str[0]=value_int_jueduizhi+48;
write_data('-');
write_data(str[0]);
}
else if((-100<value_int)&&(value_int<=-10))
{
value_int_jueduizhi=operator2_int-operator1_int;
value_int_ge=value_int_jueduizhi%10;
str[0]=value_int_ge+48;
value_int_shi=value_int_jueduizhi/10;
str[1]=value_int_shi+48;
write_data('-');
write_data(str[1]);
write_data(str[0]);
}
else if(value_int<=-100)
{
value_int_jueduizhi=operator2_int-operator1_int;
value_int_ge=value_int_jueduizhi%10;//
str[0]=value_int_ge+48;
value_int_shi=value_int_jueduizhi/10%10;
str[1]=value_int_shi+48;
value_int_bai=value_int_jueduizhi/100;
str[2]=value_int_bai+48;
write_data('-');
write_data(str[2]);
write_data(str[1]);
write_data(str[0]);
}
break;
}
for(i=0;i<=15;i++)
{
array[i]='\0';
}
jj=0;
}
/****************************************對兩位整數進行開方運算*************************************/
else if(array[2]=='K'&&array[3]=='=')
{
va1_shi=array[0]-48;
va1_ge=array[1]-48;
value_int=va1_shi*10+va1_ge;
value_float=sqrt(value_int);
sprintf(str,"%1.4f",value_float);
write_data(str[0]);
write_data(str[1]);
write_data(str[2]);
write_data(str[3]);
write_data(str[4]);
for(i=0;i<=15;i++)
{
array[i]='\0';
}
jj=0;
}
/*****************正弦函式******************************************************/
else if(array[0]=='S')
{
/****************一位整數****************/
if(array[2]=='=')
{
value_int=array[1]-48;
value_float= value_int*(3.141592/180);//弧度
value_float=sin(value_float);
sprintf(str,"%1.6f",value_float);
write_data(str[0]);
write_data(str[1]);
write_data(str[2]);
write_data(str[3]);
write_data(str[4]);
write_data(str[5]);
write_data(str[6]);
write_data(str[7]);
for(i=0;i<=15;i++)
{
array[i]='\0';
}
jj=0;
}
/****************兩位整數****************/
else if(array[3]=='=')
{
va1_shi=array[1]-48;
va1_ge=array[2]-48;
value_int=va1_shi*10+va1_ge;//度數
value_float= value_int*(3.141592/180);//弧度
value_float=sin(value_float);
sprintf(str,"%1.6f",value_float);
write_data(str[0]);
write_data(str[1]);
write_data(str[2]);
write_data(str[3]);
write_data(str[4]);
write_data(str[5]);
write_data(str[6]);
write_data(str[7]);
for(i=0;i<=15;i++)
{
array[i]='\0';
}
jj=0;
}
/***********************三位整數***********************/
else if(array[4]=='=')
{
va1_shi=array[2]-48;
va1_ge=array[3]-48;
va1_bai=array[1]-48;
value_int=va1_bai*100+va1_shi*10+va1_ge;//度數
value_float=value_int*(3.141592/180);//弧度
value_float=sin(value_float);
sprintf(str,"%1.5f",value_float);
write_data(str[0]);
write_data(str[1]);
write_data(str[2]);
write_data(str[3]);
write_data(str[4]);
write_data(str[5]);
write_data(str[6]);
for(i=0;i<=15;i++)
{
array[i]='\0';
}
jj=0;
}
/***********************小數點前1位***********************/
else if((array[2]=='.')&&(array[5]=='='))
{
va1_shi=array[3]-48;
va1_ge=array[4]-48;
va1_bai=array[1]-48;
value_float=va1_bai+va1_shi*0.1+va1_ge*0.01;//度數
value_float=value_float*(3.141592/180);//弧度
value_float=sin(value_float);
sprintf(str,"%1.5f",value_float);
write_data(str[0]);
write_data(str[1]);
write_data(str[2]);
write_data(str[3]);
write_data(str[4]);
write_data(str[5]);
write_data(str[6]);
for(i=0;i<=15;i++)
{
array[i]='\0';
}
jj=0;
}
/***********************小數點前2位***********************/
else if((array[3]=='.')&&(array[6]=='='))
{
va1_shi=array[2]-48;
va1_ge=array[5]-48;
va1_bai=array[4]-48;
va1_qian=array[1]-48;
value_float=va1_qian*10+va1_bai+va1_shi*0.1+va1_ge*0.01;//度數
value_float=value_float*(3.141592/180);//弧度
value_float=sin(value_float);
sprintf(str,"%1.5f",value_float);
write_data(str[0]);
write_data(str[1]);
write_data(str[2]);
write_data(str[3]);
write_data(str[4]);
write_data(str[5]);
write_data(str[6]);
for(i=0;i<=15;i++)
{
array[i]='\0';
}
jj=0;
}
/***********************小數點前3位***********************/
else if((array[4]=='.')&&(array[7]=='='))
{
va1_shi=array[5]-48;
va1_ge=array[6]-48;
va1_bai=array[3]-48;
va1_qian=array[2]-48;
va1_wan=array[1]-48;
value_float=va1_wan*100+va1_qian*10+va1_bai+va1_shi*0.1+va1_ge*0.01;//度數
value_float=value_float*(3.141592/180);//弧度
value_float=sin(value_float);
sprintf(str,"%1.5f",value_float);
write_data(str[0]);
write_data(str[1]);
write_data(str[2]);
write_data(str[3]);
write_data(str[4]);
write_data(str[5]);
write_data(str[6]);
for(i=0;i<=15;i++)
{
array[i]='\0';
}
jj=0;
}
}
/****************第六問 兩位運算元 (加 減 塍 除) 兩位運算元 (加 減 塍 除)兩位運算元*******************/
else if(array[8]=='=')
{
va1_shi=array[0]-48;
va1_ge=array[1]-48;
operator1_int=va1_shi*10+va1_ge;//運算元1
operator1=array[2];
operator2=array[5];
va2_ge=array[4]-48;
va2_shi=array[3]-48;
operator2_int=va2_shi*10+va2_ge;//運算元2
va3_ge=array[7]-48;
va3_shi=array[6]-48;
operator3_int=va3_shi*10+va3_ge;//運算元3
if(operator1=='/')
{
/******先除 再加 範圍10.0101-108.9000**********/
if(operator2=='+')
{
value_float=(operator1_int/(float)operator2_int)+operator3_int;
sprintf(str,"%.4f",value_float);
write_data(str[0]);
write_data(str[1]);
write_data(str[2]);
write_data(str[3]);
write_data(str[4]);
write_data(str[5]);
write_data(str[6]);
write_data(str[7]);
write_data(str[8]);
write_data(str[9]);
}
/******先除 再除****範圍0.0010-0.9900******/
if(operator2=='/')
{
value_float=(operator1_int/(float)operator2_int)/operator3_int;
sprintf(str,"%.6f",value_float);
write_data(str[0]);
&