久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 8619|回復: 2
打印 上一主題 下一主題
收起左側

單片機計算器源程序(矩陣鍵盤+數碼管顯示)原理圖與Proteus仿真 代碼注釋很詳細

[復制鏈接]
跳轉到指定樓層
樓主
矩陣鍵盤+數碼管顯示組成的一個簡易計算器單片機項目
下面是單片機計算器的proteus仿真原理圖(工程文件可到本帖附件中下載):


單片機計算器源程序如下:
  1. //#include <reg51.h>
  2. # include <STC12C5A60S2.h>
  3. # define uchar unsigned char
  4. # define uint32 unsigned long int
  5. # define sint32 signed long int
  6. # define vtime        3000   //定時3ms,一幀8*3=24ms,頻率=40Hz
  7. //共陰數碼管段碼表
  8. uchar code distable[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0X00,0x40,0x31};
  9. //位選碼表
  10. uchar  code numi[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
  11. //顯示緩存
  12. uchar V_ram[]={0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10};
  13. uchar        error=0,wi=0,dot1=0,dot2=0,dot=0xff;  //位選循環變量
  14. uint32        num1=0,num2=0,num=0,sum=0;
  15. void dispsum();
  16. void delay(uchar);
  17. uchar scan_key();
  18. main()                                                 //m1:m0  00=標準;   01=推挽;   10=輸入;   11=開漏輸出
  19. {
  20.         uchar        ni,nj,fn='+',key_V=0,dotp=0,j,k,i=0;
  21.         uint32        temp=0;
  22.         //m1:m0  00=標準;   01=推挽;   10=輸入;   11=開漏輸出
  23.         P1M1 = 0X0f;
  24.         P1M0 = 0XF0;        //設定低4位為輸入,高4位為輸出
  25.         P0M1 = 0X00;
  26.         P0M0 = 0Xff;
  27.         P2M1 = 0X00;
  28.         P2M0 = 0Xff; //設定P0,P2推挽輸出
  29.           TMOD = 0X01; //設定定時器0為16位計數方式
  30.           TH0 = (65536-vtime )/256;
  31.           TL0 = (65536-vtime )%256; //賦定時器0初值
  32.           ET0 = 1;  //開定時器0中斷
  33.           EA = 1;          //開總中斷
  34.            TR0 = 1;  //啟動定時器0計數
  35.         //sum=123456;

  36.         while(1)
  37.           {
  38.                 key_V=scan_key();
  39.                 //dispsum();
  40.                 if(key_V)
  41.                 {
  42.                         //有鍵按下
  43.                         key_V--;
  44.                         switch(key_V)
  45.                         {
  46.                            case 0:
  47.                            case 1:
  48.                            case 2:
  49.                            case 3:
  50.                            case 4:
  51.                            case 5:
  52.                            case 6:
  53.                            case 7:
  54.                            case 8:
  55.                            case 9:
  56.                                            if((num+i)==0)        
  57.                                         {        //如果是第一個數字輸入,則清黑屏
  58.                                                 dot=0xff; //關閉小數點
  59.                                                 for(j=0;j<8;j++)
  60.                                                          V_ram[j]=0x10;         //清黑屏
  61.                                         }
  62.                                    num=num*10+key_V;  //鍵盤輸入的數字轉化為十進制的數值
  63.                                         if(i==8)  //如果顯示緩沖滿了
  64.                                         {
  65.                                                 i=7;
  66.                                                 for(j=0;j<7;j++)
  67.                                                          V_ram[j]=V_ram[j+1];//顯示緩存串行移位
  68.                                         }
  69.                                         V_ram[i]=key_V;          //鍵值放入顯示緩存
  70.                                         i++;
  71.                                         break;

  72.                                 case 10:  //dot          小數點符號
  73.                                         dotp=i;                  //記錄下小數點位置
  74.                                         dot=dotp-1;  //顯示小數點
  75.                                         break;

  76.                                 case 11:   //+         加法符號
  77.                                         for(j=0;j<8;j++)
  78.                                                  V_ram[j]=0x10;         //清黑屏
  79.                                         num1=num;                         //獲取從鍵盤輸入的第一個數值
  80.                                         if(dotp==0)
  81.                                         {
  82.                                                 dot1=0;
  83.                                         }
  84.                                         else
  85.                                         {
  86.                                                 dot1=i-dotp;
  87.                                         }
  88.                                         ni=i;
  89.                                         dotp=0;
  90.                                         dot=0xff;
  91.                                         num=0;
  92.                                         fn='+';
  93.                                         i=0;
  94.                                         break;

  95.                                 case 12:   //-           減法符號
  96.                                         for(j=0;j<8;j++)
  97.                                                  V_ram[j]=0x10;          //清黑屏
  98.                                         num1=num;                          //獲取從鍵盤輸入的第一個數值
  99.                                         if(dotp==0)
  100.                                         {
  101.                                                 dot1=0;
  102.                                         }
  103.                                         else
  104.                                         {
  105.                                                 dot1=i-dotp;
  106.                                         }
  107.                                         ni=i;
  108.                                         dotp=0;
  109.                                         dot=0xff;
  110.                                         num=0;
  111.                                         fn='-';
  112.                                         i=0;
  113.                                         break;

  114.                                 case 13:   //*                  乘法符號
  115.                                         for(j=0;j<8;j++)
  116.                                                  V_ram[j]=0x10;           //清黑屏
  117.                                         num1=num;                           //獲取從鍵盤輸入的第一個數值
  118.                                         if(dotp==0)
  119.                                         {
  120.                                                 dot1=0;
  121.                                         }
  122.                                         else
  123.                                         {
  124.                                                 dot1=i-dotp;
  125.                                         }
  126.                                         ni=i;
  127.                                         dotp=0;
  128.                                         dot=0xff;
  129.                                         num=0;
  130.                                         fn='*';
  131.                                         i=0;
  132.                                         break;

  133.                                 case 14:   // /                         除法符號
  134.                                         for(j=0;j<8;j++)
  135.                                                  V_ram[j]=0x10;                //清黑屏
  136.                                         num1=num;                           //獲取從鍵盤輸入的第一個數值
  137.                                         if(dotp==0)
  138.                                         {
  139.                                                 dot1=0;
  140.                                         }
  141.                                         else
  142.                                         {
  143.                                                 dot1=i-dotp;
  144.                                         }
  145.                                         ni=i;
  146.                                         dotp=0;
  147.                                         dot=0xff;
  148.                                         num=0;
  149.                                         fn='/';
  150.                                         i=0;
  151.                                         break;

  152.                                 case 15:   //=                  等于符號
  153.                                         if(dotp==0)                   //計算第二個運算數的小數位數
  154.                                         {
  155.                                                 dot2=0;
  156.                                         }
  157.                                         else
  158.                                         {
  159.                                                 dot2=i-dotp;
  160.                                         }
  161.                                         dotp=0;
  162.                                         nj=i;
  163.                                         temp=1;
  164.                                         if(fn!='*')
  165.                                         {        if(dot1>dot2)                //第一個運算數與第二個運算進行對齊
  166.                                                 {
  167.                                                         for(j=dot1-dot2;j>0;j--)
  168.                                                         {
  169.                                                                         //if(num>0x19999999)error=1;
  170.                                                                         num=num*10;
  171.                                                                         nj++;
  172.                                                                         if(nj>9)
  173.                                                                         {
  174.                                                                                 j--;
  175.                                                                                 for(k=j;k>0;k--)
  176.                                                                                         num1=num1/10;
  177.                                                                                         dot1=dot1-j;
  178.                                                                                 break;
  179.                                                                         }

  180.                                                         }
  181.                                                 }
  182.                                                 else
  183.                                                 {
  184.                                                         for(j=dot2-dot1;j>0;j--)
  185.                                                         {
  186.                                                                         //if(num1>0x19999999)error=1;
  187.                                                                         num1=num1*10;
  188.                                                                         ni++;
  189.                                                                         if(ni>9)
  190.                                                                         {
  191.                                                                                 j--;
  192.                                                                                 for(k=j;k>0;k--)
  193.                                                                                         num=num/10;
  194.                                                                                         dot2=dot2-j;
  195.                                                                                 break;
  196.                                                                         }
  197.                                                         }
  198.                                                 }
  199.                                         }
  200.                                         //準備好后,進行運算
  201.                                         if(fn=='+')         //做加法運算
  202.                                         {
  203.                                                 sum=num+num1;
  204.                                                 if(sum<(num|num1))error=1;
  205.                                                 dispsum();           //顯示對齊后的運算結果
  206.                                                 if(dot2>dot1)        //顯示實際小數點的位置
  207.                                                         dot=dot-dot2;
  208.                                                 else
  209.                                                         dot=dot-dot1;
  210.                                                 i=0;         //計算結束,初始化關鍵變量
  211.                                                 num1=0;
  212.                                                 num=0;
  213.                                                 break;
  214.                                         }

  215.                                         if(fn=='-')          //做減法運算
  216.                                         {

  217.                                                 if(num1<num)         //判斷結果是負還是正
  218.                                                 {
  219.                                                         sum=num-num1;
  220.                                                 }
  221.                                                 else
  222.                                                         sum=num1-num;
  223.                                                 dispsum();          //顯示對齊后的運算結果
  224.                                                 if(num>num1)  //是負數則第一位顯示“-”,其它位順序往后顯示
  225.                                                 {
  226.                                                         for(j=7;j>0;j--)
  227.                                                                  V_ram[j]=V_ram[j-1]; //順序往后顯示
  228.                                                         V_ram[0]=0x11;        //第一位顯示“-”
  229.                                                         dot++;          //小數點也順延一位
  230.                                                 }
  231.                                                 if(dot2>dot1)         //顯示實際小數點的位置
  232.                                                         dot=dot-dot2;
  233.                                                 else
  234.                                                         dot=dot-dot1;

  235.                                                 i=0;        //計算結束,初始化關鍵變量
  236.                                                 num1=0;
  237.                                                 num=0;
  238.                                                 break;
  239.                                         }
  240.                                         if(fn=='*')           //做乘法運算
  241.                                         {
  242.                                                 sum=num1*num;
  243.                                                 if((ni+nj)>10)error=1;
  244.                                                 dispsum();        //顯示對齊后的運算結果
  245.                                                 //if(dot2>dot1)  //顯示實際小數點的位置
  246.                                                         dot=dot-dot2-dot1;
  247.                                                 //else
  248.                                                 //        dot=dot-dot1-dot1;
  249.                                                 i=0;         //計算結束,初始化關鍵變量
  250.                                                 num1=0;
  251.                                                 num=0;
  252.                                                 break;
  253.                                         }
  254.                                         if(fn=='/')                //做除法運算
  255.                                         {
  256.                                                 sum=num1/num;
  257.                                                 dispsum();         //顯示對齊后的運算結果,對于除法,就是實際結果
  258.                                                 temp=num1%num; //顯示小數部分
  259.                                                   for(j=dot;j<7;j++)
  260.                                                   {
  261.                                                         temp=temp*10;
  262.                                                         V_ram[j+1]=temp/num;
  263.                                                         temp=temp%num;
  264.                                                         if(temp==0)break;
  265.                                                 }
  266.                                                 i=0;        //計算結束,初始化關鍵變量
  267.                                                 num1=0;
  268.                                                 num=0;
  269.                                                 break;
  270.                                         }
  271.                                         break;
  272.                                                 
  273.                                    default:
  274.                                         break;   
  275.                         }
  276.                    delay(200);//延時去抖
  277.                 }
  278.                
  279.            }

  280. }

  281. void t0_isp() interrupt 1
  282. {
  283.         uchar dm,wx;
  284.           TH0 = (65536-vtime )/256;
  285.           TL0 = (65536-vtime )%256; //賦定時器0初值
  286.           dm=distable[V_ram[wi]];        //取顯示段碼
  287.          wx=numi[wi];                           //取位選碼
  288.         P2=0x00;                           //關顯示
  289.         //P0=dm;                                   //段碼賦給P0口
  290.         if(dot==wi)
  291.         {
  292.                 P0=dm|0x80;                  //點亮位選的那個數碼管+小數點
  293.         }
  294.         else
  295.         {
  296.                 P0=dm;                                   //點亮位選的那個數碼管
  297.         }
  298.         P2=wx;
  299.         wi++;
  300.         if(wi==8)wi=0;
  301. }
  302. /////////////////////////////////////
  303. uchar         scan_key()
  304. {
  305.                 uchar        i,j,vlume=0,temp[4]={0xef,0xdf,0xbf,0x7f};
  306.                 for(j=0;j<4;j++)
  307.                 {
  308.                         P1=temp[j];
  309.                         i=P1|0xf0;
  310.                         if(i != 0xff) //判斷按鍵
  311.                         {        //有鍵按下
  312.                                 i=~i;
  313.                                 if(i==4)i=3;
  314.                                 if(i==8)i=4;
  315.                                 i--;  // 計算按鍵所在行號(0--3)
  316.                                 vlume=i*4+j+1;        //計算鍵值
  317.                                 //delay(200);//延時去抖
  318.                         }
  319.                 }
  320.                 return        vlume;
  321. }
  322. ////////////////////////////////////////  
  323. void delay(uchar k )
  324. {
  325.         uchar x,y,z;
  326.         for(x=k;x>0;x--)
  327.         for(y=20;y>0;y--)
  328.         for(z=250;z>0;z--);
  329. }
  330. ////////////////////////////////////////
  331. void        dispsum()
  332. {
  333.         uchar        temp[10]=0,k,j;
  334.         uint32        temp1;
  335.         if(error==1)
  336.         {
  337.                 V_ram[0]=0x0e;
  338.                 V_ram[1]=0x12;
  339.                 for(j=2;j<8;j++)
  340.                         V_ram[j]=0x10;                //清黑屏
  341.                 dot=0xff;
  342.                 error=0;
  343.                 num=0;
  344.                 return;
  345.         }
  346.         temp1=sum;
  347.         for(k=0;k<10;k++)
  348.         {
  349.                
  350.                 temp[k]=temp1%10;  // sum的個位開始放入temp數組,最多可放10位
  351.                 temp1=temp1/10;           //
  352.                 if(temp1==0)
  353.                 {        // 如果商為零
  354.                         dot=k;                 //當前位小數點點亮
  355.                         for(j=0;j<8;j++)
  356.                         {
  357.                                 if(k==0xff)
  358.                                 {
  359.                                         V_ram[j]=0x10;        // 清黑屏
  360.                                 }
  361.                                 else
  362.                                 {
  363.                                         V_ram[j]=temp[k];        // 把sum中的數從高位依次放入顯示緩存
  364.                                         k--;


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

最后給大家分享一些我們老師給的一些經典的單片機程序源碼, 一共有十多個.都有詳細的注釋,然大家快速的理解每一行代碼的意思。而且有proteus仿真原理圖。大家可以直接驗證程序的對錯.


本系列所有源碼打包下載地址(含proteus仿真工程文件和源程序):
http://www.zg4o1577.cn/bbs/dpj-82474-1.html

本例程下載:
計算器.rar (100.85 KB, 下載次數: 89)

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏4 分享淘帖 頂 踩
回復

使用道具 舉報

沙發
ID:525751 發表于 2019-5-2 21:27 | 只看該作者
感謝分享 好東西啊
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 特级黄一级播放 | 中文字幕在线一区二区三区 | 国产日韩精品视频 | 成人av在线播放 | 怡红院免费的全部视频 | 日韩精品在线播放 | 欧美一区永久视频免费观看 | 亚洲欧美激情精品一区二区 | 欧美极品在线视频 | 51ⅴ精品国产91久久久久久 | 国产成人精品一区二区三 | 日本福利视频免费观看 | 97起碰 | 超碰导航 | 日韩精品一区二区久久 | 中文字幕第一页在线 | 欧美亚洲视频在线观看 | 精精精精xxxx免费视频 | 久久黄色网 | 国产乱人伦 | 日韩欧美在线观看视频网站 | 久久国产高清 | 色吧综合网 | 久久综合久久久 | 欧美亚洲网站 | 婷婷色国产偷v国产偷v小说 | www.国产一区 | 成人影院在线 | 久久久久无码国产精品一区 | 夜夜骑综合 | 欧美黄色片 | 一区二区精品视频 | 日本成人毛片 | 日韩欧美在线播放 | 日本一区二区三区在线观看 | 国产一区二区在线免费播放 | 国产美女精品视频免费观看 | 亚洲欧美中文日韩在线 | 97色伦网 | 欧美国产日韩在线 | av一区二区三区四区 |