欧美极品高清xxxxhd,国产日产欧美最新,无码AV国产东京热AV无码,国产精品人与动性XXX,国产传媒亚洲综合一区二区,四库影院永久国产精品,毛片免费免费高清视频,福利所导航夜趣136

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 6572|回復: 4
收起左側

單片機+1602制作一個能四則運算,連續運算的小型算術型計算器

  [復制鏈接]
ID:500784 發表于 2019-10-10 18:39 | 顯示全部樓層 |閱讀模式
摘要:計算器是我們生活中常用的工具,在我們生活中不可或缺。本次設計是設計一個算術型計算器,該計算器能夠完成簡單的四則運算,還可以實現連續運算。本次是以51單片機為運算核心,以LCD1602為顯示的進行硬件上的設計,在軟件上以Keil4進行軟件編程,以Proteus進行仿真調試,設計出一個能夠完成簡單的四則運算,實現連續運算的小型算術型計算器。

正文:
一、設計概述
1. 課題意義
    計算器有鍵盤部分、單片機、顯示部分三部分組成,鍵盤部分主要完成輸入功能;單片機主要完成數據處理功能,包括確定按鍵,完成運算,以及輸出數據;顯示器部分主要完成單片機輸出的顯示。基本掌握計算器的設計原理和LCD1602的顯示原理,進而熟悉C51的編程和調試方法。
2. 系統功能
   能夠完成簡單的四則運算,還可以實現連續運算的小型算術型計算器。
   硬件設計上通過Proteus進行電路原理圖和仿真運行圖的設計,軟件設計上以Keil4為基礎進行軟件編程,將編程生成的.hex文件放入在Proteus已畫好的原理圖中調試,觀察設計結果,并對代碼進行修改。

二、硬件設計
                             [size=9.0000pt] 1 [size=9.0000pt]總原理圖 圖片15.png
     
1.按鍵設計
矩陣鍵盤的原理是見I/O口分為行線和列線,按鍵設置在跨接行線和列線的交點上,列線通過上拉電阻接正電源,進而形成基本的4x4行列式鍵盤。本次設計以矩陣鍵盤為基本的輸入按鍵分別為123+456-789x0CLR=/ 形成計算器對應的基本的數字鍵和功能鍵     



圖片14.png
顯示設計

LCD1602是一種專門用來顯示字母、數字、符號等的點陣型液晶模塊,它由若干個5X7或者5X11等點陣字符位組成,每個點陣字符位都可以顯示一個字符,每位之間有一個點距的間隔,每行之間也有間隔,起到了字符間距和行間距的作用,因此它比較適合用在計算器的顯示。
圖片13.png
三、軟件設計
1. 按鍵掃描
   本次設計中在軟件上使用了反轉法進行按鍵的掃描,其過程為先讓行輸出全為0列輸出全為1讀取與按鍵相接的P1口的狀態,讀取按鍵的列值,然后讓行輸出全為1列輸出全為0讀取與按鍵相接的P1口的狀態,讀取按鍵的行值,根據行值和列值可知其鍵值。
0.jpg
                           [size=9.0000pt]    4按鍵掃描流程圖[size=9.0000pt]          

2.顯示設計
LCD1602是一個16字雙行的顯示模塊,在使用LCD1602之前我們應該先對其進行初始化,其初始化的內容有光標設置、顯示設置和清屏指令等。初始化完成后從其參考手冊可知LCD1602中已經存儲有基本字模數據,所以想要在LCD1602中顯示字符,只需要對LCD1602寫入該字符相對應的ASCII碼即可顯示出相應的字符。LCD1602的寫入可分為寫數據和寫命令,當要寫入數據時其對應的狀態為RS=1RW=0E為下降沿,然后通過單片機I/O口寫入相應的數據。當要寫入命令時其對應的狀態為RS=0RW=0E為下降沿,然后通過單片機I/O口寫入相應的命令。 0.jpg
                             [size=9.0000pt]5  LCD1602寫指令圖
3.鍵值處理
     首先我們初始化液晶顯示器,然后顯示出第一個被按下的數,并且使光標右移,如果有第二個數按下,則據繼續顯示,以此類推,然后把所有顯示出來的數換算成一個數,如果按下+”號,則顯示出“+”,并且同理顯示出“+”號后面按下的數字,然后調用加子程序,運算出結果,如果按下的是“-,則調用減子程序,如果按下“*”,則調用乘子程序,如果按下“/”,則調用除子程序。然后再調用顯示結果子程序,顯示出結果。
0.jpg
                          6鍵值運算流程圖


四、系統測試
1.加法測試
   圖片9.png


2.減法測試
圖片8.png

3.乘法測試
圖片7.png


4.除法測試
圖片5.png

5.連續運算測試
圖片4.png 圖片3.png


五、結論
經過調試可知此次設計已經基本達到要求,該計算器能夠完成簡單的四則運算,還可以實現連續運算。但只能進行整數的運算,無法進行浮點型數據運算,運算的連續運行需要一個個數的連續運算,無法做到一次性連續運算。
七、附錄
1.系統電路圖
         

2.實物運行圖
0.png

單片機源程序如下:
  1. /* 實現兩個數的運算,每個數的位數至少可以八位  */
  2. #include<reg52.h>        
  3. #include<math.h>               
  4. typedef unsigned char uint8;
  5. typedef unsigned int uint16;
  6. #define GPIO_KEY P1
  7. sbit rw=P2^5;
  8. sbit rs=P2^6;
  9. sbit e=P2^7;
  10. sbit k1=P3^0;
  11. uint8  num='N';                      //鍵值
  12. uint16 k0,k2,k3;          // 數組位
  13. uint8 fuhao;                //定義具體的那個符號,是加減還是乘除。
  14. uint8 flag,r;               //定義符號鍵標志位,小數點標志位和繼續運算標志位 這個是統稱
  15. float a,b,c,zheng,xiao;         //定義運算數據的第一個和第二個及等于的數變量
  16. uint8  shuzi1[5]={0},shuzi2[5]={0},shuzi3[4]={0};
  17. uint8 code dat1[]={1,2,3,0x2b-0x30, 4,5,6,0x2d-0x30, 7,8,9,0x78-0x30, 0,0x2e-0x30,0x3d-0x30,0xfd-0x30 };//保存顯示的數據 123+ 456- 789* 0.CLR /
  18. void delay(uint16 i)
  19. {  uint16 x,y;
  20. for(x=0;x<i;x++)
  21. for(y=0;y<114;y++);        
  22. }
  23. void lcdcommand(uint8 m)   //寫命令
  24. {
  25.         delay(1);
  26.         rs=0;
  27.         rw=0;
  28.         e=0;
  29.         P0=m;
  30.         e=1;
  31.         delay(1);
  32.         e=0;
  33. }
  34. void lcddata(uint8 dat)          //寫數據
  35. {
  36.         delay(1);
  37.         rs=1;
  38.         rw=0;
  39.         e=0;
  40.         P0=dat;
  41.         e=1;
  42.         delay(1);
  43.         e=0;
  44.         rs=0;
  45. }
  46. void lcdcsh()        //初始化         
  47. {
  48.         delay(5);
  49.         lcdcommand(0x38); //功能設定 8位總線 兩行 5X7點陣
  50.         delay(5);
  51.         lcdcommand(0x38);
  52.         lcdcommand(0x38);
  53.         lcdcommand(0x0c); // 開顯示 無光標
  54.         lcdcommand(0x06); //光標左移
  55.         lcdcommand(0x01); // 清屏
  56.         lcdcommand(0x80);//數據從左上開始
  57.         num='N';
  58.         flag=0;
  59.         fuhao=0;
  60.         a=0;
  61.         b=0;
  62.         c=0;
  63.    zheng=xiao=0;;
  64.         k0=0;k2=0;k3=0;

  65. }
  66. void shuchu(float e)                                        //在屏幕上顯示數值e
  67. {
  68. char shuzu[10];
  69.   long z;  
  70.   int x=0;
  71.   float f;
  72.          
  73.     (long)z=e;                          //整數處理
  74.         if(z==0)
  75.         lcddata('0');

  76.         while(z!=0)
  77.         {        shuzu[x]=z%10;
  78.             z=z/10;
  79.                 x++;
  80.         }
  81.   for(x=x-1;x>=0;x--)
  82.         lcddata(shuzu[x]+0x30);

  83.         (long)z=e;                                                    //小數處理
  84. (float)f=e-z;

  85. if(f>0.000)
  86. {        x=0;
  87.    lcddata('.');
  88.    z=f*1000;
  89.           while(z!=0)
  90.         {        shuzu[x]=z%10;
  91.             z=z/10;
  92.                 x++;
  93.         }
  94.   for(x=x-1;x>=0;x--)
  95.         lcddata(shuzu[x]+0x30);

  96. }
  97. }

  98. void fuzhi()        // 顯示與向數組賦值
  99. {        
  100.                         
  101.                         if(flag==0)         //是否按下符號鍵
  102.                            {
  103.                              delay(50);
  104.                  if(dat1[num]=='.')
  105.                                  r=1;
  106.                        if((r==0)&&(k0<5))
  107.                            {
  108.                             shuzi1[k0]=dat1[num];
  109.                                 k0++;
  110.                                 lcddata(0x30+dat1[num]);
  111.                                 }
  112.                            else if((r==1)&&(k3<4))
  113.                           {
  114.                           
  115.                             shuzi3[k3]=dat1[num];
  116.                                 k3++;
  117.                                 lcddata(0x30+dat1[num]);
  118.                                 }
  119.                           }
  120.          r=0;
  121.                  if(flag==1)         //是否按下符號鍵
  122.                            {
  123.                              delay(50);
  124.                  if(dat1[num]=='.')
  125.                                  r=1;
  126.                        if((r==0)&&(k2<5))
  127.                            {
  128.                             shuzi2[k2]=dat1[num];
  129.                                 k2++;
  130.                                 lcddata(0x30+dat1[num]);
  131.                                 }
  132.                            else if((r==1)&&(k3<4))
  133.                           {
  134.                           
  135.                             shuzi3[k3]=dat1[num];
  136.                                 k3++;
  137.                                 lcddata(0x30+dat1[num]);
  138.                                 }
  139.                         }

  140. }                  
  141. void  sz(uint8 s[8],int x)                                                  //數組轉為數值
  142. {
  143.   int i,j;
  144.   zheng=0;
  145.   xiao=0;
  146.   i=0;                                         //整數
  147.   while(x>0)                                   
  148.    {
  149.          zheng=zheng*10+s[i];
  150.             i++;
  151.          x--;
  152.    }
  153. i=1;                                                   //小數
  154. j=k3;  
  155. while(j>0)
  156. {
  157. xiao=xiao*10+s[i];
  158. i++;
  159. j--;
  160. }
  161.   
  162. for(;k3>0;k3--)
  163. xiao=xiao/10;
  164. zheng=zheng+xiao;
  165. k0=k2=k3=0;         
  166. }         
  167. void KeyDown(void)
  168. {
  169.         char L=0;
  170.         GPIO_KEY=0x0f;
  171.         if(GPIO_KEY!=0x0f)//讀取按鍵是否按下
  172.         {
  173.                 delay(10);//延時10ms進行消抖
  174.                 if(GPIO_KEY!=0x0f)//再次檢測鍵盤是否按下
  175.                 {        
  176.                         //測試列
  177.                         GPIO_KEY=0X0F;
  178.                         switch(GPIO_KEY)
  179.                         {
  180.                                 case(0X07):        num=0;break;
  181.                                 case(0X0b):        num=1;break;
  182.                                 case(0X0d): num=2;break;
  183.                                 case(0X0e):        num=3;break;
  184.                         }
  185.                         //測試行
  186.                         GPIO_KEY=0XF0;
  187.                         switch(GPIO_KEY)
  188.                         {
  189.                                 case(0X70):        num=num;break;
  190.                                 case(0Xb0):        num=num+4;break;
  191.                                 case(0Xd0): num=num+8;break;
  192.                                 case(0Xe0):        num=num+12;break;
  193.                         }
  194.                         while((L<50)&&(GPIO_KEY!=0xf0))         //檢測按鍵松手檢測
  195.                         {
  196.                                 delay(10);
  197.                                 L++;
  198.                         }
  199.                 }
  200.         }
  201. }
  202. void banduan()
  203. {         
  204.    switch(fuhao)
  205.    {
  206.    case 0:                     
  207.                      sz(shuzi1,k0);
  208.                                        a=zheng;
  209.                                 lcdcommand(0x01);
  210.                                                   lcdcommand(0x40+0x80);
  211.                             shuchu(a);
  212.                                                 b=0;
  213.                                                 flag=0;
  214.                                                 fuhao=0;     //全部清除為0
  215.                                                 zheng=0;
  216.                                                 xiao=0;         
  217.                                                 break;



  218.     case 1:                  
  219.                              
  220.                             lcdcommand(0x40+0x80);
  221.                                                 c=a+b;
  222.                                                 lcddata(0x3d); //顯示等于號=
  223.                                                 shuchu(c);
  224.                                                 a=0;
  225.                                                 b=0;
  226.                                                 flag=0;
  227.                                                 fuhao=0;     //全部清除為0
  228.                                                 zheng=0;
  229.                                                 xiao=0;   
  230.                                                 break;

  231.      case 2:               
  232.                                   lcdcommand(0x40+0x80);
  233.                                        
  234.                                                 if(a>b)
  235.                                         {        c=a-b;
  236.                                         lcddata(0x3d);         //顯示等于號=
  237.                                         }
  238.                                                 else if(a<b)
  239.                                                 {
  240.                                                 c=b-a;
  241.                                                 lcddata(0x3d);                                    //顯示等于號=
  242.                                                 lcddata(0x2d);                             //顯示負號-
  243.                                                  }
  244.                                                  if(a==b)
  245.                                                  c=0;
  246.                                                 shuchu(c);
  247.                                                 a=0;
  248.                                                 b=0;
  249.                                                 flag=0;
  250.                                                 fuhao=0;  //全部清除為0
  251.                                                 zheng=0;
  252.                                                 xiao=0;        
  253.                                                 break;

  254.      case 3:               
  255.                                                 lcdcommand(0x40+0x80);
  256.                                                 c=a*b;
  257.                                                 lcddata(0x3d); //顯示等于號=
  258.                                                 shuchu(c);
  259.                                                 a=0;
  260.                                                 b=0;
  261.                                                 flag=0;
  262.                                                 fuhao=0; //全部清除為0
  263.                                                 zheng=0;
  264.                                                 xiao=0;        
  265.                                                 break;

  266.      case 4:                        
  267.                                                 lcdcommand(0x40+0x80);
  268.                                                 c=a/b;                                                         
  269.                                                 lcddata(0x3d); //顯示等號
  270.                                                 shuchu(c);
  271.                                                 a=0;
  272.                                                 b=0;
  273.                                                 flag=0;
  274.                                                 fuhao=0; //全部清除為0
  275.                                                 zheng=0;
  276.                                                 xiao=0;
  277.                                        
  278.                                                 break;
  279.         }

  280. }

  281. void main()
  282. {         
  283.   
  284.   
  285.   
  286.     lcdcsh();

  287. while(1)
  288. { num='N';
  289.    KeyDown();
  290.    if(num==13)
  291.    {
  292.        lcdcommand(0x01);//清零
  293.                                                   
  294.                    flag=0;
  295.                    fuhao=0;
  296.                     a=0;
  297.                      b=0;
  298.                        c=0;
  299.                zheng=xiao=0;
  300.                            k0=k2=k3=0;
  301.    }
  302. while(1)
  303. {         
  304.   num='N';
  305.      KeyDown();
  306.   if(num==0||num==1||num==2||num==4||num==5||num==6||num==8||num==9||num==10||num==12||num==16)        //1-9-0-.
  307.          fuzhi();
  308.      if(num==13)
  309.    {
  310.        lcdcommand(0x01);//清零
  311.                                                   
  312.                    flag=0;
  313.                    fuhao=0;
  314.                     a=0;
  315.                      b=0;
  316.                        c=0;
  317.                zheng=xiao=0;
  318.                            k0=k2=k3=0;
  319.                                break;
  320.         }


  321.    if(num==3||num==7||num==11||num==15)
  322.    {
  323.    
  324.         flag=1;
  325.         switch(num)
  326.         {   case 3: fuhao=1;    break;
  327.         case 7:          fuhao=2;  break;
  328.                 case 11: fuhao=3;   break;
  329.                 case 15: fuhao=4;   break;

  330.         }
  331.                 sz(shuzi1,k0);
  332.                 c=zheng;

  333. loop:                a=c;        
  334.                         lcdcommand(0x01);
  335.                         lcdcommand(0x80);
  336.                         shuchu(a);
  337.                         lcddata(0x30+dat1[num]);
  338.                         break;
  339.      }
  340.    }
  341.    
  342.   while(1)
  343.   {                    
  344.    num='N';
  345.      KeyDown();
  346.   if(num==0||num==1||num==2||num==4||num==5||num==6||num==8||num==9||num==10||num==12)        //1-9-0
  347.          fuzhi();
  348.           if(num==13)
  349.    {
  350.        lcdcommand(0x01);//清零
  351.                                                   
  352.                    flag=0;
  353.                    fuhao=0;
  354.                     a=0;
  355.                      b=0;
  356.                        c=0;
  357.                zheng=xiao=0;
  358.                            k0=k2=k3=0;
  359.               break;
  360.    
  361. ……………………

  362. …………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼

所有程序51hei提供下載:
1.c.zip (2.41 KB, 下載次數: 129)



圖片6.png

評分

參與人數 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎勵!

查看全部評分

回復

使用道具 舉報

無效樓層,該帖已經被刪除
ID:572991 發表于 2019-11-15 21:41 | 顯示全部樓層
你的程序不能用,我親測
回復

使用道具 舉報

ID:860860 發表于 2020-12-15 19:29 來自觸屏版 | 顯示全部樓層
這個是只能1位數4則運算嗎
回復

使用道具 舉報

5#
無效樓層,該帖已經被刪除
ID:861681 發表于 2020-12-19 12:39 來自觸屏版 | 顯示全部樓層
可以混合四則運算嗎?比如1+2*2
回復

使用道具 舉報

ID:904193 發表于 2022-12-8 19:15 | 顯示全部樓層
寫的好仔細
回復

使用道具 舉報

8#
無效樓層,該帖已經被刪除
您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表