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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

51單片機+LCD12864的簡易計算器Proteus仿真源程序

  [復制鏈接]
跳轉到指定樓層
樓主
ID:505058 發(fā)表于 2021-3-23 21:09 | 只看該作者 |只看大圖 回帖獎勵 |倒序瀏覽 |閱讀模式
之前看到網上利用51和12864做計算器的資源比較少,找了很久才找到了一個帖子是用12864做的計算器,于是下載下來后做了一定程度的改進,于是想分享出來讓更多吧友看到,也歡迎各位留言評論,咱們一起學習,個人的思想還是很狹隘的,一個人想問題時思緒容易走進死胡同出不來,希望各位吧友指出不足和改進意見。附件是仿真和程序,用keil5寫的,keil4可能打不開哦(反正我用keil4打不開的),仿真也是protues8.6做的,低版本也可能打不開。

仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)


單片機源程序如下:
  1. #include<reg52.h>
  2. #include<array.h>
  3. #include<stdio.h>
  4. #include<string.h>
  5. #define uint unsigned int
  6. #define uchar unsigned char

  7. sbit E=P2^0;
  8. sbit RW=P2^1;
  9. sbit RS=P2^2;
  10. sbit CS2=P2^3;
  11. sbit CS1=P2^4;
  12. sbit RST=P2^5;
  13. sbit BEEP=P2^6;

  14. uchar  hang,lie;            //行,列
  15. float  dat1,dat2,count; //運算值
  16. uchar  keynum;                    //按鍵返回值(0~17)
  17. uchar  x;               //按鍵所對應的字符在字符表中的行號
  18. uchar  keyfun;                    //運算方式選擇(1:*, 2:+, 3:-, 4:/)

  19. void delay(uchar i)            //延遲10*n微秒
  20. {
  21.         while(i--);
  22. }

  23. void delay_ms(uchar n) //延遲n毫秒
  24. {
  25.         uchar i,j;
  26.         for(i=n;n>0;n--)
  27.                 for(j=120;j>0;j--);
  28. }


  29. /********************************************************/
  30. /*********************檢測工作狀態(tài)***********************/
  31. //void checkbusy(void)
  32. //{
  33. //     unsigned int timeout = 0;
  34. //     E  = 0;
  35. //     RS = 0;
  36. //     RW = 1;
  37. //     E  = 1;
  38. //     while((P0 & 0x80)&& ++timeout != 0);//忙狀態(tài)檢測,等待超時時間為60ms
  39. //     E  = 0;
  40. //}


  41. /********************************************************/
  42. /************************寫命令**************************/
  43. void write_cmd(uchar cmd)
  44. {
  45. //        checkbusy();
  46.         RS=0;
  47.         RW=0;
  48.         E=1;
  49.         P0=cmd;
  50.         delay(20);
  51.         E=0;
  52. }

  53. /****************************************************/
  54. /***********************寫數(shù)據(jù)***********************/
  55. void write_dat(uchar dat)          
  56. {       
  57. //        checkbusy();               
  58.         RS=1;
  59.         RW=0;
  60.         E=1;
  61.         P0=dat;
  62.         delay(20);
  63.         E=0;
  64. }


  65. /****************************************************/
  66. /*********************設置頁與列*********************/
  67. void set(uchar page,uchar col)
  68. {
  69.         page=page|0xb8;         //頁的首地址為0xb8
  70.         col=col|0x40;         //列的首地址為0x40
  71.         write_cmd(col);
  72.         write_cmd(page);
  73. }

  74. /****************************************************/
  75. /*******************選擇左、右屏*********************/
  76. void Select_Screen(uchar swich)
  77. {
  78.          switch(swich)
  79.          {
  80.           case 0:CS1=CS2=0;break;          //全屏
  81.           case 1:CS1=0;CS2=1;break;          //左屏
  82.           case 2:CS1=1;CS2=0;break;          //右屏
  83.           default:break;
  84.          }
  85. }

  86. /***************************************************/
  87. /********************LCD初始化**********************/
  88. void Lcd_Init()
  89. {
  90.         uchar i,j,k=0;
  91.         RST=0;
  92.         delay(10);
  93.         RST=1;
  94.         write_cmd(0xc0);//設置顯示起始行11xxxxxx
  95.         write_cmd(0x3f);//0x3f顯示開,0x3e顯示關
  96.         Select_Screen(0);
  97.         set(0,0);
  98.         for(i=0;i<8;i++)
  99.         {
  100.             for(j=0;j<64;j++)
  101.                         write_dat(0x00);
  102.                         k++;
  103.                         set(k,0);
  104.         }
  105.     lie=2;hang=3;keyfun=0;
  106.         dat1=0.0,dat2=0.0,count=0.0;
  107. }

  108. /*****************************************************/
  109. /********************計算窗口清空*********************/
  110. void Clear_jisuan()
  111. {
  112.          uchar i,j;
  113.         Select_Screen(0);
  114.         for(i=3;i<6;i++)                //從第三頁開始寫入數(shù)據(jù)0x00,清空計算窗口
  115.         {
  116.             for(j=0;j<64;j++)
  117.                 {
  118.                         set(i,j);
  119.                         write_dat(0x00);
  120.                 }
  121.         }
  122.         lie=2;hang=3;keyfun=0;
  123.         dat1=0.0,dat2=0.0,count=0.0;
  124. }


  125. /**************************************************/
  126. /********************顯示字符**********************/
  127. void Display_zifu(uchar n)
  128. {         
  129.         uchar i;                                         //列數(shù)小于64時
  130.         if(lie<64)
  131.         {
  132.            Select_Screen(1);                 //開左屏
  133.            set(hang,lie);                         //設置行,列
  134.            for(i=0;i<6;i++)
  135.            write_dat(zifu[n++]);         //寫入數(shù)據(jù)
  136.              lie=lie+7;                                 //每輸出一個字符列數(shù)加6
  137.            if(hang>7)                                 //行數(shù)大于7時回到初始值
  138.               hang=3;
  139.         }
  140.         else                                                 //列數(shù)大于64時
  141.         {
  142.           Select_Screen(2);
  143.           set(hang,lie-64);
  144.           for(i=0;i<6;i++)
  145.                 write_dat(zifu[n++]);
  146.           lie=lie+7;
  147.         if(lie>123)
  148.         {  
  149.            lie=0;hang++;
  150.            Select_Screen(1);
  151.         }
  152.            if(hang>7)
  153.            hang=3;
  154.         }
  155. }

  156. /******************************************************/
  157. /***********將運算結果轉化為字符串而后顯示*************/
  158. void Display_string(uchar page,uchar col,float num)
  159. {
  160.            uchar str[20];
  161.          uchar tmp[16],i,j,k,c;
  162.          int  len;
  163.          if((int)num==(int)(num+0.99999))//如果為整數(shù)
  164.          {
  165.           sprintf(str,"%d",(int)num);     //將結果轉化為字符串
  166.           len=sprintf(str,"%d",(int)num); //sprintf函數(shù)的返回值為字符串的長度,不含'/0'
  167.      }
  168.          else                                                          //如果為小數(shù)
  169.          {
  170.           sprintf(str,"%.3f",num);                  //將結果轉化為字符串
  171.           len=sprintf(str,"%.3f",num);  
  172.          }
  173.          
  174.          if(col>63)                                                  //列數(shù)大于63開右屏
  175.          {
  176.           Select_Screen(2);
  177.           col=col-64;
  178.          }
  179.          
  180.          for(i=0;i<len;i++)                        //將字符串逐個顯示
  181.          {
  182.                  if(col<63)                                //列數(shù)小于63開左屏
  183.                 {Select_Screen(1);}
  184.                 c=(str[i]-42)*6;                //數(shù)組第一行*號的ASCII值為42,每個數(shù)組中的相應元素減去42得到其在數(shù)組中的行數(shù)
  185.                 for(j=0;j<10;j++)
  186.                 {tmp[j]=zifu[c];}                //將數(shù)組zifu相應字符的ASCII碼輸送給數(shù)組tmp

  187.                 set(page,col);
  188.                 for(k=0;k<6;k++)
  189.                 write_dat(zifu[c++]);        //寫入數(shù)據(jù)
  190.                
  191.                 col=col+6;                                //每寫一個字符列數(shù)加6,繼續(xù)寫入下一個字符
  192.                 delay(100);
  193.          }         
  194. }


  195. /*****************************************************/
  196. /***********************顯示漢字**********************/
  197. void Display_Project(uchar screen,uchar page,uchar col,uchar n,uchar table[][32])
  198. {         
  199.          uchar i,temp[32];         
  200.          for(i=0;i<16;i++)                   //將table數(shù)組中的相應漢字的ascii碼輸送給數(shù)組temp
  201.          temp[i]=table[n][i];
  202.          for(i=16;i<32;i++)
  203.          temp[i]=table[n][i];       
  204.          
  205.          Select_Screen(screen);                           
  206.          set(page,col);         
  207.          for(i=0;i<16;i++)                   //寫漢字的上半部分
  208.          write_dat(temp[i]);
  209.          
  210.          set(page+1,col);
  211.          for(i=0;i<16;i++)                   //寫漢字的下半部分
  212.          write_dat(temp[i+16]);          
  213. }

  214. /***********************************************************/
  215. /******************** 響鈴 *********************************/
  216. //void play()
  217. //{   
  218. //       
  219. //        BEEP=0;
  220. //        delay_ms(1000);
  221. //        BEEP=1;
  222. //
  223. //}



  224. /***********************************************************/
  225. /********************選擇計算類型***************************/
  226. float calulate()
  227. {
  228.         switch(keyfun)
  229.         {
  230.                 case 1: count=dat2*dat1;dat1=count;break;
  231.                 case 2: count=dat2+dat1;dat1=count;break;       
  232.                 case 3: count=dat2-dat1;dat1=count;break;
  233.                 case 4: count=dat2/dat1;dat1=count;break;
  234.                 default:        break;
  235.         }
  236.         return(count);
  237. }

  238. /********************************************************/
  239. /***********************計算過程*************************/                                               
  240. void cal_process()
  241. {                          
  242.         uchar str_mul[10],len_mul;
  243.         if(x!=19)
  244.         {Display_zifu(x*6);}          
  245.         while((P3&0xf0)!=0xf0);        //按鍵按下有效,顯示刷新
  246.        
  247.         switch(keynum)
  248.         {                               
  249.                 case 0:
  250.                 case 1:
  251.                 case 2:
  252.                 case 3:
  253.                 case 4:
  254.                 case 5:
  255.                 case 6:
  256.                 case 7:
  257.                 case 8:
  258.                 case 9:        dat1=dat1*10+keynum;break;  //例如:輸入12,初始dat1=0;則dat1=0*10+1=1;dat1=1*10+2=12
  259. /* * */        case 10:calulate();dat2=dat1;dat1=0;keyfun=1;break;         
  260.                
  261. /* + */        case 11:calulate();dat2=dat1;dat1=0;keyfun=2;break;         
  262.                
  263. /* - */        case 12:calulate();dat2=dat1;dat1=0;keyfun=3;break;         
  264.                
  265. /* / */        case 13:calulate();dat2=dat1;dat1=0;keyfun=4;break;                                                     
  266.                
  267. /* = */        case 14:hang=5;lie=0;Display_zifu(19*6);                          
  268.                         switch(keyfun)
  269.                    {
  270.                         case 1: count=dat2*dat1;break;
  271.                         case 2: count=dat2+dat1;break;       
  272.                         case 3: count=dat2-dat1;break;
  273.                            case 4: count=dat2/dat1;break;
  274.                         default:break;
  275.                    }
  276.                            if(count<999999999)
  277.                            {
  278.                              if(keyfun==1)
  279.                              {
  280.                                 if((len_mul=sprintf(str_mul,"%d",count))<8)        //多位整數(shù)乘法若結果大于6則顯示?
  281.                                            Display_string(5,6,count);
  282.                              }
  283.                                  else if(keyfun==4)
  284.                                  {
  285.                                      if(dat1!=0)                                       //除數(shù)為0則輸出?
  286.                                          Display_string(5,6,count);
  287.                                  }
  288.                                  else
  289.                                  Display_string(5,6,count);
  290.                            }
  291.                           
  292.                            else Display_zifu(20*6);break;                          

  293.                 default: break;
  294.         }

  295. }

  296. /********************************************************/
  297. /*****************矩陣按鍵掃描(逐行掃描)*****************/
  298. void keyscan()
  299. {
  300.         uchar key;       
  301.         P3=0xfe;                                //令第一行為0,判斷列
  302.         if(P3!=0Xfe)
  303.         {
  304.            delay(100);                        //消抖
  305.           if(P3!=0xfe)
  306.           {
  307.              key=P3&0xf0;
  308.                  switch(key)
  309.                  {
  310.                   case 0xe0:keynum=7; x=13;cal_process();break;  // 7
  311. ……………………

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

所有資料51hei提供下載:
計算器12864帶字.rar (139.63 KB, 下載次數(shù): 195)

評分

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

查看全部評分

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

使用道具 舉報

沙發(fā)
ID:1113217 發(fā)表于 2024-3-17 06:58 | 只看該作者
找了好久終于找到用12864屏幕的作者了,給作者點個贊
回復

使用道具 舉報

板凳
ID:1113285 發(fā)表于 2024-3-25 16:39 | 只看該作者
這個屏幕我喜歡
回復

使用道具 舉報

地板
ID:1134669 發(fā)表于 2024-11-1 23:32 | 只看該作者
好東西,
很需要
回復

使用道具 舉報

5#
ID:1135525 發(fā)表于 2024-11-5 14:39 | 只看該作者
藍色那個線是怎么接的?
回復

使用道具 舉報

6#
ID:1134947 發(fā)表于 2024-11-13 15:49 | 只看該作者
好東西,很需要
回復

使用道具 舉報

7#
ID:508994 發(fā)表于 2024-12-4 20:47 | 只看該作者
好東西,謝謝分享,
回復

使用道具 舉報

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

本版積分規(guī)則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 一级看片免费视频囗交动图 | 国产99久久精品一区二区永久免费 | 91免费在线视频 | 精品欧美一区二区三区久久久 | 欧洲精品码一区二区三区免费看 | 天天色影视综合 | 日韩视频在线一区 | 91久久国产精品 | 国产精品久久久亚洲 | 日本三级电影在线观看视频 | 亚洲一区中文字幕在线观看 | 美国av毛片 | 国产精品一级 | 国产精品日韩在线观看 | 伊人精品 | 黑人一级黄色大片 | 福利视频三区 | 视频1区| 日韩在线一区二区 | h在线免费观看 | 免费在线观看av的网站 | 视频一区二区中文字幕日韩 | 美女拍拍拍网站 | 91五月婷蜜桃综合 | 欧美日韩电影免费观看 | 日本精品视频 | 成人免费在线 | 欧美日日| 在线观看视频亚洲 | 日日干日日操 | 国产91在线精品 | av在线播放网站 | 免费一二区| 日韩精品一区二区三区在线观看 | 欧美视频一区二区三区 | 欧美日本一区 | 最新日韩在线 | 免费一区 | 国产一区亚洲 | 国产欧美精品区一区二区三区 | 欧美国产视频 |