1. 程式人生 > >基於51微控制器的科學計算器

基於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]); 
                   &