找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 3067|回復(fù): 0
收起左側(cè)

單片機(jī)計(jì)算器簡單功能實(shí)現(xiàn)

[復(fù)制鏈接]
ID:857654 發(fā)表于 2020-12-20 21:04 | 顯示全部樓層 |閱讀模式
話不多說直接上圖

計(jì)算器

計(jì)算器



主函數(shù)代碼
  1. #include <config.h>
  2. #include <1602.h>
  3. #include <keypad4_4.h>        

  4. u8 equation[17]; // 算式緩沖區(qū)
  5. u8 n=0;//當(dāng)前字符在緩沖區(qū)的下標(biāo)

  6. void delay_ms(u16 x)//毫秒延時(shí)函數(shù)
  7. {u16 i,j;
  8. for(i=0;i<x;i++)
  9.     for(j=0;j<115;j++);
  10. }   

  11. void disch(u8 ch)//若算式長度超過一行,則左移一位再顯示,否則在當(dāng)前位置顯示
  12. {
  13.   u8 i;
  14.   if(n==16){ //若算式長度超過一行,則左移一位
  15.                        for(i=0;i<17;i++)
  16.                           equation[i]=equation[i+1];
  17.                        equation[15]=ch;//將數(shù)字存入算式緩沖區(qū)尾部                          
  18.                            equation[16]='\0';//給算式緩沖區(qū)尾部加結(jié)束標(biāo)記
  19.                            LCD1602_disstr(equation,0,0); //顯示算式
  20.                    }
  21.   
  22.   else     {        //若算式長度未超過一行
  23.                    equation[n++]=ch;//將運(yùn)算符存入算式緩沖區(qū)尾部
  24.                            equation[n]='\0';//給算式緩沖區(qū)尾部加結(jié)束標(biāo)記
  25.                            LCD1602_disch(ch);//在當(dāng)前位置顯示
  26.                    }
  27. }
  28.                         
  29. void main()        //主函數(shù)
  30. {

  31.   u8 key;//按鍵編碼
  32.   u8 ch;//輸入的字符
  33.   u8 flag=0; //        狀態(tài)標(biāo)記
  34.   u8 ac;//第一行光標(biāo)當(dāng)前位置
  35.   u32 num1=0;        // 數(shù)1
  36.   u32 num2=0;        // 數(shù)2
  37.   u8 op1;//運(yùn)算符1
  38.   u8 op2;//運(yùn)算符2
  39.   u32 result=0; //        運(yùn)算結(jié)果

  40.   
  41.   LCD1602_Init( );//1602初始化
  42.   while(1)
  43.   {
  44.           key=keypad4_4();  //掃描按鍵
  45.           if(key!=16)              //如果有鍵按下
  46.           {        
  47.             ch=keyval4_4[key]; //獲取用戶輸入的字符
  48.                   if(ch=='c') {        //輸入cancel,回到初始狀態(tài),所有數(shù)據(jù)清空,清屏
  49.                                                  flag=0;//轉(zhuǎn)到初始狀態(tài)
  50.                                                 num1=0;num2=0;//將數(shù)1、數(shù)2清空
  51.                                                 equation[0]='\0';n=0;//清空算式緩沖區(qū)
  52.                                                 LCD1602_clear( ); //清屏
  53.                                         }  
  54.                 else
  55.                 {
  56.                         if(ch<'0'||ch>'9')
  57.                           {          //輸入運(yùn)算符時(shí),切換狀態(tài)
  58.                                 if(flag==1)        flag=2;         //數(shù)1輸入狀態(tài)下輸入運(yùn)算符1,進(jìn)入運(yùn)算符1輸入狀態(tài)
  59.                                 if(flag==3)        flag=4;        //數(shù)2輸入狀態(tài)下輸入運(yùn)算符2,進(jìn)入計(jì)算狀態(tài)
  60.                                 if(flag==5)        {        //運(yùn)算結(jié)束狀態(tài)下,若繼續(xù)輸入運(yùn)算符則繼續(xù)運(yùn)算
  61.                                                                 if(ch=='=')          flag=5;          //再次輸入'='無效
  62.                                                      else                 {        //輸入運(yùn)算符則繼續(xù)運(yùn)算
  63.                                                                                                 flag=2;//轉(zhuǎn)到運(yùn)算符1輸入狀態(tài)
  64.                                                                                                 num1=result;//將上次結(jié)果保存到數(shù)1
  65.                                                                                                 num2=0;//清除數(shù)2
  66.                                                                                         }
  67.                                                         }
  68.                         }
  69.                         else
  70.                         {          //輸入數(shù)字時(shí),切換狀態(tài)
  71.                                   if(flag==0)                flag=1;//初始狀態(tài)下輸入數(shù)字,進(jìn)入數(shù)1輸入狀態(tài)
  72.                                 if(flag==2)                flag=3;        //運(yùn)算符1輸入狀態(tài)下輸入數(shù)字,進(jìn)入數(shù)2輸入狀態(tài)
  73.                                 if(flag==5)        {        //運(yùn)算結(jié)束狀態(tài)下,若繼續(xù)輸入數(shù)字則重新開始運(yùn)算
  74.                                                                 flag=1;        //轉(zhuǎn)到數(shù)1輸入狀態(tài)
  75.                                                                 num1=0;num2=0;//將數(shù)1、數(shù)2清空
  76.                                                                 equation[0]='\0';n=0; //清空算式緩沖區(qū)
  77.                                                                 LCD1602_clear( ); //清屏
  78.                                                         }
  79.                         }
  80.                         
  81.                         if(flag==1) {   //數(shù)1輸入狀態(tài),存入數(shù)1,若算式長度超過一行,則左移一位顯示,否則在當(dāng)前位置顯示
  82.                                                         num1=num1*10+(ch-'0'); //將數(shù)字存入數(shù)1
  83.                                                         disch(ch);//若算式長度超過一行,則左移一位再顯示,否則在當(dāng)前位置顯示
  84.                                                 }
  85.                         
  86.                         if(flag==2)        {        //運(yùn)算符1輸入狀態(tài),輸入'='無效,若輸入其他運(yùn)算符則保存,若算式長度超過一行,則左移一位顯示,否則在當(dāng)前位置顯示
  87.                                                         if(ch!='=') {
  88.                                                                                         op1=ch;        //保存運(yùn)算符1                                                                                       
  89.                                                                                     disch(ch);//若算式長度超過一行,則左移一位再顯示,否則在當(dāng)前位置顯示                                                                                
  90.                                                                                 }
  91.                                                 }
  92.                         
  93.                         if(flag==3)        {  //數(shù)2輸入狀態(tài),存入數(shù)2,若算式長度超過一行,則左移一位顯示,否則在當(dāng)前位置顯示
  94.                                                         num2=num2*10+(ch-'0'); //將數(shù)字存入數(shù)2
  95.                                                         disch(ch);//若算式長度超過一行,則左移一位再顯示,否則在當(dāng)前位置顯示
  96.                                                 }                        
  97.                         
  98.                         if(flag==4)        {  //根據(jù)運(yùn)算符1開始計(jì)算                                       
  99.                                                    switch(op1)
  100.                                        {
  101.                                                                    case '+':result= num1+num2;break;
  102.                                                                 case '-':result= num1-num2;break;
  103.                                                                 case '*':result= num1*num2;break;
  104.                                                                 case '/':result= num1/num2;break;
  105.                                                    }
  106.                                                    ac=RdACAdr( );//讀取第一行當(dāng)前光標(biāo)地址
  107.                                                    LCD1602_disnum(result,1,0);//從第二行行首開始顯示結(jié)果
  108.                            retACAdr(ac);//恢復(fù)到第一行光標(biāo)地址
  109.                                                    op2=ch; //保存運(yùn)算符2
  110.                                                    if(op2=='=')          flag=5;         //若運(yùn)算符2為'=',轉(zhuǎn)到運(yùn)算結(jié)束狀態(tài)(需要進(jìn)一步判斷是重新開始運(yùn)算,還是繼續(xù)運(yùn)算?)
  111.                                                    else         {        
  112.                                                                                            flag=2;        //若運(yùn)算符2不為'=',則繼續(xù)運(yùn)算,進(jìn)入運(yùn)算符1輸入狀態(tài)
  113.                                                                                         num1=result; //將上次結(jié)果保存到數(shù)1
  114.                                                                                         num2=0;//清除數(shù)2
  115.                                                                                         op1=op2;//更新運(yùn)算符1                                                                                             
  116.                                                                                         disch(ch);//若算式長度超過一行,則左移一位再顯示,否則在當(dāng)前位置顯示
  117.                                                                                 }
  118.                                                 }   
  119.                 }
  120.         }
  121.   }         
  122. }
復(fù)制代碼



shiyan06.zip

108.11 KB, 下載次數(shù): 8, 下載積分: 黑幣 -5

計(jì)算器

評分

參與人數(shù) 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎(jiǎng)勵(lì)!

查看全部評分

回復(fù)

使用道具 舉報(bào)

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表