找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開始

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

簡(jiǎn)易單片機(jī)計(jì)算器的課程設(shè)計(jì)實(shí)驗(yàn)報(bào)告(程序+實(shí)驗(yàn)記錄)

[復(fù)制鏈接]
ID:477682 發(fā)表于 2019-2-18 13:58 | 顯示全部樓層 |閱讀模式
一、 實(shí)驗(yàn)題目
基于51單片機(jī)的簡(jiǎn)易計(jì)算器
二、 內(nèi)容
1、實(shí)驗(yàn)內(nèi)容
              該系統(tǒng)通過單片機(jī)控制,實(shí)現(xiàn)對(duì)4*4鍵盤掃描進(jìn)行實(shí)時(shí)的按鍵檢測(cè),并把檢測(cè)數(shù)據(jù)存儲(chǔ)下來。整個(gè)計(jì)算器系統(tǒng)的工作過程為:首先存儲(chǔ)單元初始化,顯示初始值和鍵盤掃描,判斷按鍵位置,得出按鍵值,單片機(jī)則對(duì)數(shù)據(jù)進(jìn)行儲(chǔ)存與相應(yīng)處理轉(zhuǎn)換,之后送入數(shù)碼管動(dòng)態(tài)顯示。整個(gè)系統(tǒng)可分為三個(gè)主要功能模塊:功能模塊一,實(shí)時(shí)鍵盤掃描;功能模塊二,數(shù)據(jù)轉(zhuǎn)換為了數(shù)碼管顯示;功能模塊三,數(shù)碼管動(dòng)態(tài)顯示。
            
2、功能說明
  • 矩陣按鍵對(duì)應(yīng)表
s1 s2 s3 s4         1  2  3  +
s5 s6 s7 s8         4  5  6  -
s9 s10 s11 s12      7  8  9  *
s13 s14 s15 s16     0  clr  =  /
  • 顯示模塊
本來計(jì)劃用數(shù)碼管顯示,結(jié)果發(fā)的單片機(jī)數(shù)碼管驅(qū)動(dòng)芯片與預(yù)想的不一樣,不是通過段選,位選的方式。然后就沒看的特別懂,臨時(shí)換成了lcd1602顯示屏,驅(qū)動(dòng)程序較為固定,且顯示的也更加全面。
  • 中斷的運(yùn)用
通過中斷定時(shí)器零設(shè)置中斷,定時(shí)10s,開機(jī)10秒后,執(zhí)行中斷,自動(dòng)清零,相當(dāng)于自動(dòng)按下按鍵14。
三、 原理
見下頁。

四、 實(shí)驗(yàn)記錄
因?yàn)樵谡n堂上未記錄實(shí)驗(yàn)現(xiàn)象,所以在課下在按照自己的單片機(jī)的引腳設(shè)置更改了程序后,再將程序下載到51單片機(jī)中,得到以下實(shí)驗(yàn)結(jié)果:
剛下入程序時(shí),初始化后的顯示如下:
            
然后進(jìn)行一些簡(jiǎn)單的計(jì)算顯示:
最多可以進(jìn)行八位數(shù)的運(yùn)算:
            
五、 修改后程序框圖

六、總結(jié)
              本來在實(shí)驗(yàn)課上由于前期準(zhǔn)備不夠充分,課上經(jīng)歷了更改顯示方式,由數(shù)碼管顯示改為了1602液晶屏顯示,且在實(shí)驗(yàn)課上僅完成了計(jì)算器的功能,能夠?qū)崿F(xiàn)加減乘除的運(yùn)算,但是不能實(shí)現(xiàn)連續(xù)運(yùn)算功能。在課下又經(jīng)過充分的學(xué)習(xí)了解,成功的加上了定時(shí)器中斷,實(shí)現(xiàn)了定時(shí)清屏功能。由此可見,充足的課前準(zhǔn)備能夠極大地提高效率。
              本次實(shí)驗(yàn)滿足了設(shè)計(jì)要求,包含有矩陣按鍵的使用,定時(shí)器中斷,LCD1602外設(shè),將要求用到的內(nèi)容都成功的聯(lián)系在了一起。雖然該例子中的定時(shí)器中斷在實(shí)際生活中并不會(huì)這樣使用,不過通過這種方式,也讓我對(duì)定時(shí)器中斷的使用有了更加深刻的認(rèn)識(shí),也能夠通過定時(shí)器中斷進(jìn)行一些簡(jiǎn)單的設(shè)計(jì)。
              通過本次實(shí)驗(yàn),加深了對(duì)51單片機(jī)原理的理解與認(rèn)知,尤其是對(duì)矩陣按鍵掃描判斷,定時(shí)器中斷,LCD1602外設(shè)的應(yīng)用等方面的原理的學(xué)習(xí)也提高了一個(gè)層次。通過本次實(shí)驗(yàn),提高了自己的邏輯分析能力,發(fā)現(xiàn)問題解決問題的能力。提高了對(duì)C語言編程的理解與應(yīng)用,能夠靈活的運(yùn)用例程達(dá)到自己的設(shè)計(jì)要求,完成實(shí)驗(yàn)。
七、附錄
  1. #include "REG52.h"
  2. typedef unsigned char uint8;
  3. typedef unsigned int uint16;
  4. typedef unsigned long ulong;
  5. uint8 key;//存放按鍵值
  6. uint8 num,number,t;
  7. uint8 fuhao;//定義具體的那個(gè)符號(hào),是加減還是乘除。
  8. uint8 flag;              //定義有沒有按下符號(hào)鍵,這個(gè)是統(tǒng)稱
  9. long a,b,c,d;              //定義運(yùn)算數(shù)據(jù)的第一個(gè)和第二個(gè)及等于的數(shù)變量
  10. uint8 k; //定義小數(shù)點(diǎn)后面顯示的位數(shù)
  11. uint8 biao;

  12. sbit rs = P1^0;            
  13. sbit rw = P1^1;            
  14. sbit e = P1^2;              //LCD使能端
  15. uint8 dat1[]={1,2,3,0x2b-0x30, 4,5,6,0x2d-0x30, 7,8,9,0x2a-0x30, 0,0x01-0x30,0x3d-0x30,0x2b-0x30 };//保存顯示的數(shù)據(jù)

  16. void Delay(unsigned int);              //聲明延時(shí)函數(shù)
  17. void InterruptTimer0() ;

  18. void lcdwrc(uint8 c)                //寫指令數(shù)據(jù)
  19. {
  20.               Delay(5);
  21.               rs=0;
  22.               rw=0;
  23.               e=0;
  24.               P0=c;
  25.               e=1;
  26.               Delay(5);
  27.               e=0;
  28. }
  29. void lcdwrd(uint8 dat)                            //寫顯示數(shù)據(jù)
  30. {
  31.               Delay(5);
  32.               rs=1;
  33.               rw=0;
  34.               e=0;
  35.               P0=dat;
  36.               e=1;
  37.               Delay(5);
  38.               e=0;
  39.               rs=0;
  40. }

  41. void lcdinit()                               //lcd初始化
  42. {
  43.               Delay(7);
  44.               lcdwrc(0x38);
  45.     Delay(3);
  46.               lcdwrc(0x38);
  47.               Delay(3);
  48.               lcdwrc(0x38);
  49.               Delay(3);
  50.               lcdwrc(0x38);
  51.               lcdwrc(0x08);
  52.               lcdwrc(0x01);
  53.               lcdwrc(0x06);
  54.               lcdwrc(0x0c);
  55.               key=0;
  56.               num=0;
  57.               flag=0;
  58.               fuhao=0;
  59.               a=0;
  60.               b=0;
  61.               c=0;
  62.               d=0;
  63.               biao=0;
  64. }

  65. //函數(shù)名稱:Delay
  66. //函數(shù)功能:延時(shí)函數(shù)
  67. //入口參數(shù):uiCount-延時(shí)參數(shù),每加1增加0.5ms
  68. void Delay(unsigned int uiCount)
  69. {
  70.               unsigned char j = 244;
  71.               for(;uiCount > 0;uiCount--) while(--j);            
  72. }

  73. void keyscan()                //矩陣按鍵掃描函數(shù)
  74. {
  75.               P2=0xef;   //令第一行為0,然后判斷是哪一列按下
  76.               if(P2!=0xef)
  77.               {
  78.                             Delay(5);
  79.                             if(P2!=0xef)
  80.                             {
  81.                                           key=P2&0x0f;
  82.                                           switch(key)
  83.                                           {
  84.                                                         case 0x0e: num=0;break;                //1
  85.                                                         case 0x0d: num=1;break;                //2
  86.                                                         case 0x0b: num=2;break;                //3
  87.                                                         case 0x07: num=3;break;                //加
  88.                                           }
  89.                             }
  90.                             while(P2!=0xef);
  91.                             if(num==0||num==1||num==2)              //確認(rèn)第一行的數(shù)1,2,3
  92.                             {
  93.                                           if(flag==0)              //沒有按下符號(hào)鍵
  94.                                           {
  95.                                                         a=a*10+dat1[num];            
  96.                                           }
  97.                                           else
  98.                                           {
  99.                                                         b=b*10+dat1[num];
  100.                                           }
  101.                            
  102.                             }
  103.                             if(num==3)
  104.                             {
  105.                                           flag=1;
  106.                                           fuhao=1;//加號(hào)+            
  107.                             }
  108.                             lcdwrd(0x30+dat1[num]);
  109.               }


  110.               P2=0xdf;                                                        //令第二行為0,判斷是哪一列按下
  111.               if(P2!=0xdf)
  112.               {
  113.                             Delay(5);
  114.                             if(P2!=0xdf)
  115.                             {
  116.                                           key=P2&0x0f;
  117.                                           switch(key)
  118.                                           {
  119.                                                         case 0x0e: num=4;break;                //4
  120.                                                         case 0x0d: num=5;break;                //5
  121.                                                         case 0x0b: num=6;break;                //6
  122.                                                         case 0x07: num=7;break;                //減—
  123.                                           }            
  124.                             }
  125.                             while(P2!=0xdf);
  126.                             if(num==4||num==5||num==6)
  127.                             {
  128.                                           if(flag==0)              //沒有按下符號(hào)鍵
  129.                                           {
  130.                                                         a=a*10+dat1[num];            
  131.                                           }
  132.                                           else
  133.                                           {
  134.                                                         b=b*10+dat1[num];
  135.                                           }                                         
  136.                             }
  137.                             else
  138.                             {
  139.                                           flag=1;
  140.                                           fuhao=2;//代表減號(hào)
  141.                             }
  142.                             lcdwrd(0x30+dat1[num]);
  143.               }


  144.               P2=0xbf;                            //令第三行為0,判斷哪一列按下
  145.               if(P2!=0xbf)
  146.               {
  147.                             Delay(5);
  148.                             if(P2!=0xbf)
  149.                             {
  150.                                           key=P2&0x0f;
  151.                                           switch(key)
  152.                                           {
  153.                                                         case 0x0e: num=8;break;                //7
  154.                                                         case 0x0d: num=9;break;                //8
  155.                                                         case 0x0b: num=10;break;  //9
  156.                                                         case 0x07: num=11;break;  //乘*
  157.                                           }            
  158.                             }
  159.                             while(P2!=0xbf);
  160.                             if(num==8||num==9||num==10)
  161.                             {
  162.                                           if(flag==0)              //沒有按下符號(hào)鍵
  163.                                           {
  164.                                                         a=a*10+dat1[num];            
  165.                                           }
  166.                                           else
  167.                                           {
  168.                                                         b=b*10+dat1[num];
  169.                                           }                                         
  170.                             }
  171.                             else
  172.                             {
  173.                                           flag=1;
  174.                                           fuhao=3;//代表乘號(hào)*
  175.                             }
  176.                             lcdwrd(0x30+dat1[num]);
  177.               }


  178.               P2=0x7f;                            //令第四行為0,判斷哪一列按下
  179.               if(P2!=0x7f)
  180.               {
  181.                             Delay(5);
  182.                             if(P2!=0x7f)
  183.                             {
  184.                                           key=P2&0x0f;
  185.                                           switch(key)
  186.                                           {
  187.                                                         case 0x0e: num=12;break;  //0
  188.                                                         case 0x0d: num=13;break;  //清除rst
  189.                                                         case 0x0b: num=14;break;  //等號(hào)=
  190.                                                         case 0x07: num=15;break;  //除/
  191.                                           }            
  192.                             }
  193.                             while(P2!=0x7f);
  194.                             switch(num)
  195.                             {
  196.                                           case 12:
  197.                                                                       if(flag==0)              //沒有按下符號(hào)鍵
  198.                                                                       {
  199.                                                                                     a=a*10+dat1[num];
  200.                                                                                     lcdwrd(0x30);            
  201.                                                                       }
  202.                                                                       else
  203.                                                                       {
  204.                                                                                     b=b*10+dat1[num];
  205.                                                                                     lcdwrd(0x30);
  206.                                                                       }
  207.                                                                       break;
  208.                                          
  209.                                           case 13:
  210.                                                                       lcdwrc(0x01);              //清屏指令                                         
  211.                                                                       a=0;
  212.                                                                       b=0;
  213.                                                                       flag=0;
  214.                                                                       fuhao=0;
  215.                                                                       break;

  216.                                           case 15:
  217.                                                                       flag=1;
  218.                                                                       fuhao=4;
  219.                                                                       lcdwrd(0x2f);//除號(hào)/
  220.                                                                       break;
  221.                                                                      
  222.                                           case 14:
  223.                                                                       if(fuhao==1)//加
  224.                                                                       {
  225.                                                                                     lcdwrc(0x4f+0x80);
  226.                                                                                     lcdwrc(0x04);//設(shè)置光標(biāo)左移,屏幕不移動(dòng)
  227.                                                                                     c=a+b;
  228.                                                                                     while(c!=0)              //一位一位顯示
  229.                                                                                     {
  230.                                                                       lcdwrd(0x30+c%10);//顯示結(jié)果的最后一位在0x4f的位置
  231.                                                                                                   c=c/10;//取前面的結(jié)果數(shù)據(jù)            
  232.                                                                                     }
  233.                                                                                     lcdwrd(0x3d); //顯示等于號(hào)=
  234.                                                                                     a=0;
  235.                                                                                     b=0;
  236.                                                                                     flag=0;
  237.                                                                                     fuhao=0;//全部清除為0
  238.                                                                       }
  239.                                                                       if(fuhao==2)   //減
  240.                                                                       {
  241.                                                                                     lcdwrc(0x4f+0x80);
  242.                                                                                     lcdwrc(0x04);//設(shè)置光標(biāo)左移,屏幕不移動(dòng)
  243.                                                                                     if(a>b)
  244.                                                                                                   c=a-b;
  245.                                                                                     else
  246.                                                                                                   c=b-a;
  247.                                                                                    
  248.                                                                                     while(c!=0)              //一位一位顯示
  249.                                                                                     {
  250.                                                                       lcdwrd(0x30+c%10);//顯示結(jié)果的最后一位在0x4f的位置
  251.                                                                                                   c=c/10;//取前面的結(jié)果數(shù)據(jù)            
  252.                                                                                     }
  253.                                                                                     if(a<b)              lcdwrd(0x2d); //顯示-號(hào)
  254.                                                                                     lcdwrd(0x3d); //顯示等于號(hào)=
  255.                                                                                     a=0;
  256.                                                                                     b=0;
  257.                                                                                     flag=0;
  258.                                                                                     fuhao=0;//全部清除為0
  259.                                                                       }
  260.                                                                       if(fuhao==3)//乘法                           
  261.                                                                       {
  262.                                                                                     lcdwrc(0x4f+0x80);
  263.                                                                                     lcdwrc(0x04);//設(shè)置光標(biāo)左移,屏幕不移動(dòng)
  264.                                                                                     c=a*b;
  265.                                                                                     while(c!=0)              //一位一位顯示
  266.                                                                                     {
  267.                                                                       lcdwrd(0x30+c%10);//顯示結(jié)果的最后一位在0x4f的位置
  268.                                                                                                   c=c/10;//取前面的結(jié)果數(shù)據(jù)            
  269.                                                                                     }
  270.                                                                                     lcdwrd(0x3d); //顯示等于號(hào)=
  271.                                                                                     a=0;
  272.                                                                                     b=0;
  273.                                                                                     flag=0;
  274.                                                                                     fuhao=0;//全部清除為0            
  275.                                                                       }                           
  276.                                                       
  277.                                                                       if(fuhao==4)
  278.                                                                       {
  279.                                                                                     k=0;
  280.                                                                                     lcdwrc(0x4f+0x80);
  281.                                                                                     lcdwrc(0x04);//設(shè)置光標(biāo)左移,屏幕不移動(dòng)
  282.                                                                                     c=(long)(((float)a/b)*1000);//強(qiáng)制轉(zhuǎn)換為long。
  283.                                                                                     while(c!=0)              //一位一位顯示
  284.                                                                                     {
  285.                                                                                                   k++;
  286.                                                         lcdwrd(0x30+c%10);//顯示結(jié)果的最后一位在0x4f的位置
  287.                                                                                                   c=c/10;//取前面的結(jié)果數(shù)據(jù)
  288.                                                                                                   if(k==3)
  289.                                                                                                   {
  290.                                                                                                                 lcdwrd(0x2e);
  291.                                                                                                                 k=0;
  292.                                                                                                   }                           
  293.                                                                                     }
  294.                                                                       if(a/b<0)                //如果a比b小的話那么除的結(jié)果最高位是0
  295.                                                                                     {
  296.                                                                                                   lcdwrd(0x30);            
  297.                                                                                     }
  298.                                                                                     lcdwrd(0x3d); //顯示等號(hào)
  299.                                                                                     a=0;
  300.                                                                                     b=0;
  301.                                                                                     flag=0;
  302.                                                                                     fuhao=0;//全部清除為0
  303.                                                                       }
  304.                                                                       break;

  305.                             }
  306.               }

  307. }

  308. void InterruptTimer0() interrupt 1                            //定時(shí)器中斷0
  309. {
  310.     TH0=0xDC;              //裝初值
  311.               TL0=0x00;
  312.               number++;
  313.               if(number==100)              //定時(shí)1s
  314.               {
  315.                             number=0;
  316.                             t++;
  317.                             if(t==10)              //定時(shí)10s
  318.                             {
  319.                                           t=0;
  320.                                           lcdwrc(0x01);              //清屏指令                                         
  321.                                                                       a=0;
  322.                                                                       b=0;
  323.                                                                       flag=0;
  324.                                                                       fuhao=0;            
  325.                             }
  326.               }
  327. }
  328.                            
  329.   void main()              //主函數(shù)
  330. {
  331.               TH0=0xDC;              //裝初值
  332.               TL0=0x00;
  333.     TMOD=0x01;           //定時(shí)器0工作于16位,用于定時(shí)產(chǎn)生中斷
  334.     EA=1;                                                        //允許總中斷
  335.               ET0=1;                                                        //允許定時(shí)器0中斷
  336.               TR0=1;                                                        //開定時(shí)器0            
  337.               lcdinit();  
  338.               while(1)
  339.               {
  340.                             keyscan();                           
  341.               }                     
  342. }
復(fù)制代碼

完整的Word格式實(shí)驗(yàn)報(bào)告文檔51黑下載地址:
單片機(jī)實(shí)驗(yàn)報(bào)告.docx (1.09 MB, 下載次數(shù): 44)


評(píng)分

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

查看全部評(píng)分

回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

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

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

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