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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 1810|回復: 0
收起左側

簡易計算器的設計及實現加(減)功能

[復制鏈接]
ID:354501 發表于 2018-6-19 17:53 | 顯示全部樓層 |閱讀模式
用Proteus實現計算器功能的實現:實現加(減)功能。

單片機源程序如下:
  1. #include <reg52.h>
  2. #define uchar unsigned char
  3. #define uint unsigned int
  4. sbit rs=P0^0;
  5. sbit rw=P0^1;
  6. sbit e=P0^2;
  7. sbit k0=P1^0;
  8. sbit k1=P1^1;
  9. sbit k2=P1^2;
  10. sbit k3=P1^3;
  11. sbit k4=P1^4;
  12. sbit k5=P1^5;
  13. sbit k6=P1^6;
  14. sbit k7=P1^7;
  15. unsigned char code digit[ ]={"0123456789"};    //定義字符數組顯示數字
  16. unsigned char s,m,h,day,month,year,count;
  17. void write_dat(uchar dat);
  18. void write_com(uchar com);
  19. void keyscan();
  20. /**********************
  21. 功能說明:
  22. 顯示編碼,加上0x30,
  23. 分別為'1','2','3','+',
  24. '4','5','6','-',等
  25. **********************/
  26. uchar code table1[]=
  27. {
  28. 1,2,3,0x2b-0x30,
  29. 4,5,6,0x2d-0x30,
  30. 7,8,9,0x2a-0x30,
  31. 0,0x3d-0x30,0x01-0x30,0x2f-0x30
  32. };

  33. uchar k=0,flag=0,num,fuhao,i;

  34. long a,b,c;


  35. void delay(uint z)
  36. {
  37.     uint x,y;
  38.     for(x=z;x>0;x--)
  39.         for(y=110;y>0;y--);
  40. }
  41. /*****************************************************
  42. 函數功能:指定字符顯示的實際地址
  43. 入口參數:x
  44. ***************************************************/
  45. void WriteAddress(unsigned char x)
  46. {
  47.      write_com(x|0x80); //顯示位置的確定方法規定為"80H+地址碼x"
  48. }
  49. /******************************************************************************
  50. 函數功能:顯示小時                          
  51. ******************************************************************************/
  52. void DisplayHour()
  53. {
  54.    unsigned char i,j;
  55.         i=h/10;                //取整運算,求得十位數字
  56.         j=h%10;                //取余運算,求得各位數字
  57.    WriteAddress(0x45);     //寫顯示地址,將十位數字顯示在第2行第0列
  58.          write_dat(digit[i]);   //將十位數字的字符常量寫入LCD
  59.      write_dat(digit[j]);   //將個位數字的字符常量寫入LCD
  60.      
  61. }
  62. /******************************************************************************
  63. 函數功能:顯示分鐘                          
  64. ******************************************************************************/
  65. void DisplayMinute()
  66. {
  67.   unsigned char i,j;
  68.    i=m/10;                 //取整運算,求得十位數字
  69.         j=m%10;                //取余運算,求得各位數字
  70.    WriteAddress(0x48);     //寫顯示地址,將十位數字顯示在第2行第3列
  71.          write_dat(digit[i]);   //將十位數字的字符常量寫入LCD
  72.          write_dat(digit[j]);   //將個位數字的字符常量寫入LCD
  73.      
  74. }
  75. /******************************************************************************
  76. 函數功能:顯示秒                        
  77.   ******************************************************************************/
  78. void DisplaySecond()
  79. {
  80.    unsigned char i,j;
  81.           i=s/10;                //取整運算,求得十位數字
  82.         j=s%10;                //取余運算,求得各位數字
  83.    WriteAddress(0x4b);     //寫顯示地址,將十位數字顯示在第2行第6列
  84.          write_dat(digit[i]);   //將十位數字的字符常量寫入LCD
  85.     write_dat(digit[j]);   //將個位數字的字符常量寫入LCD
  86. }


  87. /******************************************************************************
  88. 函數功能:顯示小時                          
  89. ******************************************************************************/
  90. void DisplayYear()
  91. {
  92.    unsigned char i,j;
  93.         i=year/10;                //取整運算,求得十位數字
  94.         j=year%10;                //取余運算,求得各位數字
  95.    WriteAddress(0x07);     //寫顯示地址,將十位數字顯示在第2行第0列
  96.          write_dat(digit[i]);   //將十位數字的字符常量寫入LCD
  97.      write_dat(digit[j]);   //將個位數字的字符常量寫入LCD
  98.      
  99. }
  100. /******************************************************************************
  101. 函數功能:顯示分鐘                          
  102. ******************************************************************************/
  103. void DisplayMonth()
  104. {
  105.   unsigned char i,j;
  106.    i=month/10;                 //取整運算,求得十位數字
  107.         j=month%10;                //取余運算,求得各位數字
  108.    WriteAddress(0x0a);     //寫顯示地址,將十位數字顯示在第2行第3列
  109.          write_dat(digit[i]);   //將十位數字的字符常量寫入LCD
  110.          write_dat(digit[j]);   //將個位數字的字符常量寫入LCD
  111.      
  112. }
  113. /******************************************************************************
  114. 函數功能:顯示秒                        
  115.   ******************************************************************************/
  116. void DisplayDay()
  117. {
  118.    unsigned char i,j;
  119.           i=day/10;                //取整運算,求得十位數字
  120.         j=day%10;                //取余運算,求得各位數字
  121.    WriteAddress(0x0d);     //寫顯示地址,將十位數字顯示在第2行第6列
  122.          write_dat(digit[i]);   //將十位數字的字符常量寫入LCD
  123.     write_dat(digit[j]);   //將個位數字的字符常量寫入LCD
  124. }
  125. void keyscan2()
  126.         {if(k0==0)
  127.            {delay(5);
  128.             if(k0==0)
  129.               {
  130.                   s++;
  131.                if(s==60)
  132.                s=0;
  133.                }
  134.             }
  135.           if(k1==0)
  136.             {delay(5);
  137.              if(k1==0)
  138.                {m++;
  139.                 if(m==60)
  140.                   m=0;
  141.                 }
  142.              }
  143.                   if(k2==0)
  144.             {delay(5);
  145.              if(k2==0)
  146.                {h++;
  147.                 if(h==60)
  148.                  h=0;
  149.                 }
  150.              }
  151.      
  152.                   if(k3==0)
  153.             {delay(5);
  154.              if(k3==0)
  155.                {day++;
  156.                 if(day==30)
  157.                  day=0;
  158.                 }
  159.              }
  160.                   if(k4==0)
  161.             {delay(5);
  162.              if(k4==0)
  163.                {month++;
  164.                 if(month==13)
  165.                   month=0;
  166.                 }
  167.              }
  168.         if(k5==0)
  169.             {delay(5);
  170.              if(k5==0)
  171.                {year++;
  172.                 if(year==99)
  173.                    year=0;
  174.                 }
  175.              }

  176.           }
  177.          
  178. void keyscan()
  179. {
  180.     uchar temp;
  181.     P3=0xfe;
  182.     temp=P3;
  183.     temp=temp&0xf0;
  184.     while(temp!=0xf0)
  185.     {
  186.        delay(5);
  187.        temp=P3;
  188.        temp=temp&0xf0;
  189.        while(temp!=0xf0)
  190.        {
  191.            temp=P3;
  192.            switch(temp)
  193.            {
  194.               case 0xee:num=0;
  195.                 break;   
  196.               case 0xde:num=1;
  197.              break;
  198.               case 0xbe:num=2;
  199.              break;
  200.               case 0x7e:num=3;
  201.              break;
  202.             }   
  203.              while(temp!=0xf0)
  204.                 { temp=P3;
  205.                   temp=temp&0xf0;
  206.            }
  207.            }

  208. /*當按下1,2,3,松手后執行下面這段語句*/
  209.            if(num==0||num==1||num==2)
  210.            {
  211.                
  212.                 if(flag==0)
  213.                    a=a*10+table1[num];//如果沒有按符號鍵,符號前的數值為a
  214.                 else if(flag==1)
  215.                    b=b*10+table1[num];  //如果按了符號鍵,符號后的數值為b
  216.       
  217.                 if(k==1)    //如果之前按了'='號,再按鍵時清屏,進行下一次計算
  218.              {
  219.                  k=0;
  220.                     write_com(0x01);
  221.              }
  222.          }
  223.             else if(num==3)   //判斷按下'+'
  224.       {
  225.                  flag=1;
  226.                  fuhao=1;
  227.          }
  228.                               
  229.           i=table1[num];    //顯示按下的鍵
  230.           write_dat(0x30+i);
  231.       
  232.        }
  233.     P3=0xfd;
  234.     temp=P3;
  235.     temp=temp&0xf0;
  236.     while(temp!=0xf0)
  237.     {
  238.        delay(5);
  239.        temp=P3;
  240.        temp=temp&0xf0;
  241.        while(temp!=0xf0)
  242.        {
  243.            temp=P3;
  244.            switch(temp)
  245.            {
  246.               case 0xed:num=4;
  247.                 break;   
  248.               case 0xdd:num=5;
  249.              break;
  250.               case 0xbd:num=6;
  251.              break;
  252.               case 0x7d:num=7;
  253.              break;
  254.             }   
  255.              while(temp!=0xf0)
  256.                 { temp=P3;
  257.                  temp=temp&0xf0;
  258.            }
  259.            }
  260.          if(num==4||num==5||num==6) //判斷是否按下'4','5','6'
  261.       {
  262.              if(k==1)
  263.              {
  264.                  k=0;
  265.                     write_com(0x01);
  266.              }
  267.              if(flag==0)
  268.                 a=a*10+table1[num];
  269.              else if(flag==1)
  270.                 b=b*10+table1[num];      
  271.       }
  272.          else if(num==7)
  273.       {
  274.              flag=1;
  275.              fuhao=2;   
  276.       }
  277.          i=table1[num];     //顯示按下的鍵
  278.          write_dat(0x30+i);   

  279.        }
  280.     P3=0xfb;
  281.     temp=P3;
  282.     temp=temp&0xf0;
  283.     while(temp!=0xf0)
  284.     {
  285.        delay(5);
  286.        temp=P3;
  287.        temp=temp&0xf0;
  288.        while(temp!=0xf0)
  289.        {
  290.            temp=P3;
  291.            switch(temp)   //
  292.            {
  293.               case 0xeb:num=8;
  294.                 break;   
  295.               case 0xdb:num=9;  
  296.              break;
  297.               case 0xbb:num=10;
  298.              break;
  299.               case 0x7b:num=11;
  300.                 break;            
  301.             }   
  302.              while(temp!=0xf0)
  303.                 { temp=P3;
  304.                  temp=temp&0xf0;
  305.            }
  306.            }
  307.            if(num==8||num==9||num==10)  //判斷是否按下'7','8','9'
  308.            {
  309.                if(k==1)
  310.              {
  311.                  k=0;
  312.                     write_com(0x01);
  313.              }
  314.                if(flag==0)
  315.                   a=a*10+table1[num];
  316.                else if(flag==1)
  317.                   b=b*10+table1[num];
  318.            
  319.            }
  320.            else if(num==11)      //判斷是否按下'*'
  321.            {
  322.                 flag=1;
  323.              fuhao=3;
  324.            
  325.            }
  326.            i=table1[num];
  327.            write_dat(0x30+i);
  328.       
  329.        }
  330.        P3=0xf7;
  331.     temp=P3;
  332.     temp=temp&0xf0;
  333.     while(temp!=0xf0)
  334.     {
  335.        delay(5);
  336.        temp=P3;
  337.        temp=temp&0xf0;
  338.        while(temp!=0xf0)
  339.        {
  340.            temp=P3;
  341.            switch(temp)
  342.            {
  343.               case 0xe7:num=12;    // 0鍵
  344.                 break;   
  345.               case 0xd7:num=13;     // '='
  346.              break;
  347.               case 0xb7:num=14;  //清零鍵
  348.              break;
  349.               case 0x77:num=15;  //'/'
  350.                 break;            
  351.             }   
  352.              while(temp!=0xf0)
  353.                 { temp=P3;
  354.                  temp=temp&0xf0;
  355.                }   
  356.            }
  357.           switch(num)
  358.           {
  359.              case 12:
  360.              {
  361.                   if(k==1)
  362.              {
  363.                  k=0;
  364.                     write_com(0x01);
  365.              }
  366.                  if(flag==0)
  367.                    a=a*10;
  368.                  else if(flag==1)
  369.                    b=b*10;

  370.                    write_dat(0x30);
  371.              }
  372.                    break;
  373.              case 13:          //按=鍵
  374.            {
  375.                   k=1;
  376.                  if(fuhao==1)    //如果符號鍵是+,執行+運算
  377.            {
  378.                   
  379.                      write_com(0x80+0x4f);
  380.                      write_com(0x04);
  381.                c=a+b;
  382.                      while(c!=0)     
  383.             {
  384.                         write_dat(0x30+c%10);
  385.                   c=c/10;
  386.             
  387.            
  388.            }
  389.                     write_dat(0x3d);
  390.                  fuhao=0;
  391.                     a=0;b=0;flag=0;
  392.            }
  393.                  if(fuhao==2)
  394.            {
  395.                     write_com(0x80+0x4f);
  396.                     write_com(0x04);
  397.                   if(a>=b)
  398.            {
  399.                    c=a-b;
  400.                       while(c!=0)
  401.              {
  402.                          write_dat(0x30+c%10);
  403.                    c=c/10;
  404.                       }              
  405.             
  406.            }
  407.                     else if(a<b)
  408.            {
  409.                     c=b-a;
  410.                        while(c!=0)
  411.                  {
  412.                            write_dat(0x30+c%10);
  413.                      c=c/10;
  414.                  }
  415.                       write_dat(0x2d);
  416.            }
  417.            
  418.                     write_dat(0x3d);
  419.                    a=0;b=0;flag=0;fuhao=0;
  420.            
  421.            }
  422.                  if(fuhao==3)   //如果符號鍵是*
  423.            {
  424.                     write_com(0x80+0x4f);
  425.                     write_com(0x04);
  426.                     c=a*b;
  427.                  while(c!=0)
  428.            {
  429.                        write_dat(0x30+c%10);
  430.                     c=c/10;
  431.            }
  432.                     write_dat(0x3d);         
  433.                    a=0;b=0;flag=0;fuhao=0;
  434.            
  435.            }
  436.                  if(fuhao==4)      //如果符號鍵是/
  437.            {  
  438.                      i=0;
  439.                      write_com(0x80+0x4f);
  440.                      write_com(0x04);
  441.                     c=(long)(((float)a/b)*1000000);  //結果保留6位小數
  442.                  while(c!=0)
  443.            {
  444.                        write_dat(0x30+c%10);
  445.                     c=c/10;
  446.                  i++;

  447.                     if(i==6)        //   顯示完六位小數后,顯示·
  448.                          write_dat(0x2e);     
  449.            }
  450.                  if(a/b<=0)
  451.                      write_dat(0x30);
  452.                      write_dat(0x3d);
  453.                      a=0;b=0;flag=0;fuhao=0;
  454.            }
  455.            }
  456.               break;
  457.             case 14:
  458.                 { write_com(0x01);
  459.                  a=0;b=0;flag=0;fuhao=0;
  460.              }
  461.                  break;

  462.              case 15:
  463.                   {
  464.                     flag=1;
  465.                  fuhao=4;
  466.                    write_dat(0x30+table1[num]);
  467.       
  468.                    }
  469.                    break;
  470.       
  471.           }

  472.                
  473.        }
  474.          
  475. }
  476. /*******led1602*******/
  477. void write_com(uchar com)
  478. {
  479.    rs=0;//選擇寫指令
  480.    rw=0;
  481.    P2=com;
  482.    e=1;
  483.    delay(5);//無延時不能正常工作
  484.    e=0;
  485. }
  486. void write_dat(uchar dat)
  487. {
  488.    rs=1;//選擇寫數據
  489.    rw=0;
  490.    P2=dat;
  491.    e=1;
  492.    delay(5);//無延時不能正常工作
  493.    e=0;
  494. }
  495. void init()  //初始化
  496. {
  497.    delay(15);
  498.    write_com(0x38);
  499.    delay(6);
  500.    write_com(0x38);
  501.    delay(6);
  502.    write_com(0x38);
  503.    write_com(0x38);
  504.    write_com(0x0c); //開顯示,關光標
  505.    write_com(0x06);//光標移動 設置
  506.    write_com(0x01);//清屏
  507.    
  508. }   
  509. void geshi()
  510.      {
  511.           WriteAddress(0x00);      
  512.         write_dat('D');
  513.      WriteAddress(0x01);      
  514.     write_dat('a');   
  515.     WriteAddress(0x02);      
  516.     write_dat('t');            //將分號的字符常量寫入LCD
  517.          WriteAddress(0x03);      
  518.         write_dat('e');
  519.     WriteAddress(0x04);      
  520.         write_dat(':');
  521. WriteAddress(0x05);      
  522.         write_dat('2');
  523.         WriteAddress(0x06);      
  524.         write_dat('0');
  525.      WriteAddress(0x09);      
  526.         write_dat('-');
  527.      WriteAddress(0x0c);      
  528.         write_dat('-');   
  529.      WriteAddress(0x40);      
  530.         write_dat('T');
  531.      WriteAddress(0x41);      
  532.         write_dat('i');  
  533.     WriteAddress(0x42);      
  534.         write_dat('m');   
  535.         WriteAddress(0x43);        //寫地址,將第二個分號顯示在第2行第7列
  536.         write_dat('e');            //將分號的字符常量寫入LCD
  537.         WriteAddress(0x44);        //寫地址,將第二個分號顯示在第2行第10列
  538.         write_dat(':');            //將分號的字符常量寫入LCD
  539.          WriteAddress(0x47);      
  540.         write_dat(':');
  541.      WriteAddress(0x4a);      
  542.         write_dat(':');   
  543.          }


  544.                     
  545. void main()
  546. {   
  547.      

  548.     init();
  549.         TMOD=0x01;                 //使用定時器T0的模式1
  550.         TH0=(65536-46083)/256;    //定時器T0的高8位設置初值
  551.         TL0=(65536-46083)%256;    //定時器T0的低8位設置初值
  552.         EA=1;                     //開總中斷
  553.         ET0=1;                    //定時器T0中斷允許
  554.         TR0=1;                    //啟動定時器T0
  555.         count=0;                  //中斷次數初始化為0
  556.         s=0;                      //秒初始化為0
  557.         m=0;                      //分鐘初始化為0
  558.         h=0;                      //小時初始化為0
  559.         year=0;
  560.         month=0;
  561.         day=0;

  562.    while(1)
  563.     {  
  564.          keyscan();
  565.           if(k6==0)
  566.            { k6=0;
  567.         write_com(0x01);
  568.         while(1)
  569.                 {
  570.                 keyscan2();
  571.        geshi();
  572.            delay(5);  
  573.        DisplayHour();
  574.            delay(5);  
  575.        DisplayMinute();
  576.            delay(5);  
  577.        DisplaySecond();
  578.             delay(5);  
  579.         DisplayYear();
  580.                 delay(5);  
  581.        DisplayMonth();
  582.            delay(5);  
  583.        DisplayDay();
  584.                 delay(5);
  585.              if(k7==0)
  586.                 {
  587.                  k6=1;
  588.                  write_com(0x01);
  589.                  break;
  590.                 }
  591.           
  592.            }
  593.           
  594.           }   
  595.           
  596.     }
  597.    
  598. }

  599. /*******************************************************
  600. 函數功能:定時器T0的中斷服務函數
  601. ********************************************************/
  602. void Time0(void ) interrupt 1 using 1 //定時器T0的中斷編號為1,使用第1組工作寄存器
  603.   {
  604.          count++;                          //每產生1次中斷,中斷累計次數加1
  605.                  if(count==20)                 //如果中斷次數計滿20次
  606.                     {
  607.               count=0;                 //中斷累計次數清0
  608.                         s++;                   //秒加1                               
  609.                   if(s==60)                    //如果計滿60秒
  610.                          {
  611.                           s=0;                     //秒清0
  612.                           m++;                     //分鐘加1
  613.                      }
  614.                   if(m==60)                      //如果計滿60分
  615.                    {
  616.                            m=0;                    //分鐘清0
  617.                            h++;                    //小時加1
  618.                     }
  619.             
  620.                  if(h==24)
  621.                  {
  622.                   h=0;
  623.                  day++;
  624.                  }
  625.                  if(day==30)
  626.                  {
  627.                    day=0;
  628.                    month++;
  629.                  }
  630.                  if(month==13)
  631.                  { month=0;
  632.                   year++;
  633.                  }
  634.                  if(year==99)
  635.                  {
  636.                  year=0;
  637.                  }
  638.            TH0=(65536-46083)/256;          //定時器T0高8位重新賦初值
  639.            TL0=(65536-46083)%256;         //定時器T0低8位重新賦初值               
  640.    }
  641.   }
復制代碼

所有資料51hei提供下載:
計算器.rar (3.28 KB, 下載次數: 13)



回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 一级毛片免费 | 国产高清在线观看 | 日韩美女在线看免费观看 | av在线免费观看网站 | www.日韩欧美 | 国产精品久久久亚洲 | 国产精品久久久久久久久久免费看 | 天天综合成人网 | 一级做a爰片久久毛片免费看 | 精品国产鲁一鲁一区二区张丽 | 三级黄色片在线播放 | 一本综合久久 | 国产九一精品 | 暴草美女 | 国产精品毛片无码 | 久久草视频 | 久久躁日日躁aaaaxxxx | 久久久蜜桃一区二区人 | 国产欧美日韩精品在线观看 | 午夜视频在线视频 | 国产精品中文字幕在线 | 亚洲精品日韩欧美 | 久久久精品一区二区三区 | 一区二区三区在线观看视频 | 蜜臀久久99精品久久久久野外 | 国产一区二区三区在线 | 日日操夜夜操天天操 | 午夜欧美一区二区三区在线播放 | 国产视频线观看永久免费 | 国产精品一区二区三区四区 | 成年人免费在线视频 | 久久久精品视频免费 | 日韩中文字幕一区二区三区 | 福利影院在线看 | 国内精品久久久久久久 | 激情一区二区三区 | 日韩欧美在线视频播放 | 精品国产乱码久久久久久闺蜜 | 精品国产精品一区二区夜夜嗨 | 免费精品在线视频 | 国产成人高清成人av片在线看 |