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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

能夠實現單片機計算器與LCD1602字幕滾動的源程序

[復制鏈接]
跳轉到指定樓層
樓主
當你按計算器部分時,自動切換到計算器,按字幕滾動方式時,自動切換到字幕滾動

程序中的部分來源于他人
附件中有程序與仿真,以及51單片機開發板的程序,方便實物操作

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


單片機源程序如下:

  1. /*
  2. 接盤按鍵說明:
  3. --------------------------------------------------
  4.             |  7  |  8  |  9  |  /  |  
  5.             - - - - - - - - - - - - -
  6.             |  4  |  5  |  6  |  *  |
  7.             - - - - - - - - - - - - -
  8.             |  1  |  2  |  3  |  -  |
  9.             - - - - - - - - - - - - -
  10.                         | C   |  0  |  =  |  +  |
  11. --------------------------------------------------*/
  12. //操作簡介
  13. // 按第一個數,再按'+-*/',再按'='顯示出結果,然后按C清屏
  14. // 加最大9999+9999=19998
  15. // 減最大9999-0   =9999
  16. // 乘最大9999*9999=99980001
  17. // 除 1/9=0.1111 保留小數點后4位
  18. #include<reg51.h>
  19. #define uint unsigned int
  20. #define uchar unsigned char
  21. //--------LCD1602-------------------
  22. //P00-07==== D0-7
  23. sbit rs=P2^6;        //指令or數據
  24. sbit wela=P2^5;      //讀or寫
  25. sbit lcden=P2^7;         //使能信號
  26. //--------LCD1602-------------------
  27. //--------KEY-----------------------
  28. //P1口
  29. //--------KEY-----------------------
  30. uchar code table[]= "                ";

  31. long  int data_a,data_b;         //第一個數和第二個數
  32. long  int data_c;                        //計算結果
  33. uchar a1[16]="I love huihui";  //顯示內容
  34. sbit stop=P3^2 ;
  35. sbit sp=P3^4;
  36. sbit czs=P3^3;
  37. uchar dispaly[10];         //顯示緩沖

  38. /***************延遲函數*************/
  39. void delay(uchar z)
  40. {
  41. uchar y;
  42. for(z;z>0;z--)
  43.    for(y=0;y<110;y++);
  44. }

  45. //************************************************************************/
  46. // 描述: 延時t us函數
  47. //************************************************************************/
  48. void LCD_Delay_us(unsigned int t)
  49. {
  50.         while(t--);           //t=0,退出
  51. }
  52. //************************************************************************/
  53. // 描述: 延時t ms函數
  54. //************************************************************************/
  55. void LCD_Delay_ms(unsigned int t)
  56. {
  57.         unsigned int i,j;
  58.         for(i=0;i<t;i++)                       //執行t次循環
  59.         for(j=0;j<113;j++)                     //執行113次循環
  60.         ;
  61. }
  62. //************************************************************************/
  63. // 描述: 1602液晶寫指令
  64. //************************************************************************/
  65. void write_com(uchar com)            //1602液晶寫指令
  66. {
  67.         rs=0;                       //寫指令
  68.         lcden=0;                    //使能1602
  69.         P0=com;                     //寫入指令com
  70.         LCD_Delay_ms(1);            //延時1ms
  71.         lcden=1;                    //使能1602
  72.         LCD_Delay_ms(2);            //延時2ms  
  73.         lcden=0;                        //使能1602
  74. }
  75. //************************************************************************/
  76. // 描述:1602液晶寫數據
  77. //************************************************************************/
  78. void write_date(uchar date) //1602液晶寫數據
  79. {
  80.         rs=1;                        //寫數據
  81.         lcden=0;                     //使能1602
  82.         P0=date;                     //寫入數據date
  83.         LCD_Delay_ms(1);             //延時1ms
  84.         lcden=1;                     //使能1602
  85.         LCD_Delay_ms(2);             //延時2ms
  86.         lcden=0;                         //使能1602
  87. }
  88. //************************************************************************/
  89. // 描述:指定x,y寫入字符函數
  90. //************************************************************************/
  91. void W_lcd(unsigned char x,unsigned char y,unsigned char Data)
  92. {     
  93.          if (y == 0){write_com(0x80 + x);}   //第一行  
  94.          else{write_com(0xc0 + x);}          //第二行
  95.          write_date( Data);                  //寫入數據
  96. }
  97. //指定x,y寫入字符串函數
  98. void LCD_Write_String(unsigned char x,unsigned char y,unsigned char *s)
  99. {     
  100. if (y == 0){write_com(0x80 + x);}                 //第一行
  101. else{write_com(0xC0 + x);}                        //第二行
  102. while (*s)                                        //
  103.          {write_date( *s); s++;}                      //寫入數據
  104. }
  105. //************************************************************************/
  106. // 描述:初始化液晶,及畫面初始化
  107. //************************************************************************/
  108. void init_lcd(void)            //初始化液晶,及畫面初始化
  109. {
  110.         wela=0;                      //寫液晶
  111.         lcden=0;                     //使能1602
  112.         write_com(0x38);             //8 位總線,雙行顯示,5X7 的點陣字符
  113.         LCD_Delay_us(100);           //延時100us
  114.         write_com(0x0c);             //開顯示,無光標,光標不閃爍
  115.         write_com(0x06);             //光標右移動
  116.         write_com(0x01);             //清屏
  117.         write_com(0x80);             //DDRAM 地址歸0
  118. }
  119. //************************************************************************/
  120. // 描述: 反轉法鍵盤掃描
  121. //************************************************************************/
  122. short keycheckdown()                                /* 反轉法鍵盤掃描 */
  123. {

  124.         short temp1,temp2,temp,a=0xff;
  125.         P1=0xf0;                                                /* 輸入行值(或列值) */
  126.         LCD_Delay_ms(20);                                /* 延時 */
  127.         temp1=P1;                                                /* 讀列值(或行值) */
  128.         P1=0xff;
  129.         LCD_Delay_ms(20);                                /* 延時 */
  130.         P1=0x0f;                                                /* 輸入列值(或行值) */
  131.         LCD_Delay_ms(20);                                /* 延時 */        
  132.         temp2=P1;                                                /* 讀行值(或列值) */
  133.         P1=0xff;
  134.         temp=(temp1&0xf0)|(temp2&0xf);        /* 將兩次讀入數據組合 */
  135.         switch(temp)                                        /* 通過讀入數據組合判斷按鍵位置 */
  136.         {


  137.                 case 0x77 :a=1;break;//  按鍵+a=0x0a   
  138.                 case 0x7b :a=2; break;// 按鍵=        a=0x0e
  139.                 case 0x7d :a=3;           break;// 按鍵0a=0
  140.                 case 0x7e :a=0x0a; break;// 按鍵CEa=0x0f

  141.                 case 0xe7 :a=0x0f;break;//         按鍵/a=0x0d
  142.                 case 0xeb :a=0;break; //  按鍵9a=0x9
  143.                 case 0xed :a=0x0e;break; //  按鍵8a=0x8
  144.                 case 0xee :a=0x0b;break; //         按鍵7a=0x7

  145.                 case 0xd7 :a=0x7;break;//  按鍵*a=0x0c
  146.                 case 0xdb :a=0x8;break; //         按鍵6a=0x6
  147.                 case 0xdd :a=0x9;break; //         按鍵5a=0x5
  148.                 case 0xde :a=0x0c;break; //         按鍵4a=0x4

  149.                 case 0xb7 :a=0x4; break;// 按鍵-a=0x0b
  150.                 case 0xbb :a=0x5;break;        //  按鍵3a=3
  151.                 case 0xbd :a=0x6;break;        //  按鍵2a=2
  152.                 case 0xbe :a=0x0d;break;        //  按鍵1a=1

  153.                 default :a=0xff;
  154.         }
  155.         return a;                                                /* 返回按鍵值 */
  156. }
  157. void display_a() //顯示數據a
  158. {
  159.         dispaly[3]=data_a%10000/1000;    //千
  160.         dispaly[2]=data_a%1000/100;      //百
  161.         dispaly[1]=data_a%100/10;        //十
  162.         dispaly[0]=data_a%10;            //個

  163.         write_com(0x80+0);               //顯示數據a
  164.         if(data_a>999){        write_date('0'+dispaly[3]);}      //顯示千位
  165.         if(data_a>99){        write_date('0'+dispaly[2]);}                 //顯示百位
  166.         if(data_a>9){        write_date('0'+dispaly[1]);}     //顯示十位
  167.                               write_date('0'+dispaly[0]);      //顯示個位
  168. }

  169. void display_b() //顯示數據b
  170. {
  171.         write_com(0x80+7); //第一行
  172.         dispaly[3]=data_b%10000/1000;    //千
  173.         dispaly[2]=data_b%1000/100;      //百
  174.         dispaly[1]=data_b%100/10;        //十
  175.         dispaly[0]=data_b%10;            //個

  176. if(data_b>999){        write_date('0'+dispaly[3]); }     //顯示千位   
  177. if(data_b>99) {        write_date('0'+dispaly[2]); }    //顯示百位  
  178. if(data_b>9)  {        write_date('0'+dispaly[1]); }     //顯示十位
  179.                               write_date('0'+dispaly[0]);      //顯示個位
  180. }

  181. //計算結果
  182. void display_c(x)
  183. {

  184.         if(data_c<100000000&&data_c>-1)//溢出時顯示錯誤
  185.         {        

  186.                 dispaly[8]=data_c%1000000000/100000000;            //萬萬
  187.                 dispaly[7]=data_c%100000000/10000000;            //千萬
  188.                 dispaly[6]=data_c%10000000/1000000;                    //百萬
  189.                 dispaly[5]=data_c%1000000/100000;                    //十萬
  190.                 dispaly[4]=data_c%100000/10000;                            //萬
  191.                 dispaly[3]=data_c%10000/1000;                            //千
  192.                 dispaly[2]=data_c%1000/100;                              //百
  193.                 dispaly[1]=data_c%100/10;                                //十
  194.                 dispaly[0]=data_c%10;                                    //個
  195.                 write_com(0x80+6+0x40); //第一行
  196.                 if(x==4)
  197.                 {   
  198.                         if(data_c>99999999)        {        write_date('0'+dispaly[8]);}    //顯示萬萬
  199.                         if(data_c>9999999)        {        write_date('0'+dispaly[7]);}   //千萬
  200.                         if(data_c>999999)        {        write_date('0'+dispaly[6]);}    //百萬
  201.                         if(data_c>99999)        {        write_date('0'+dispaly[5]);}    //十萬
  202.                         if(data_b!=0)                {
  203.                                                                         write_date('0'+dispaly[4]);    //萬
  204.                                                                         write_date('.');
  205.                                                                         write_date('0'+dispaly[3]);    //千
  206.                                                                         write_date('0'+dispaly[2]);    //百
  207.                                                                         write_date('0'+dispaly[1]);    //十
  208.                                                                         write_date('0'+dispaly[0]);    //個
  209.                                                                 }
  210.                 }
  211.         else{
  212.                 if(data_c>99999999)        {        write_date('0'+dispaly[8]);}    //顯示萬萬
  213.                 if(data_c>9999999)        {        write_date('0'+dispaly[7]);}    //千萬
  214.                 if(data_c>999999)        {        write_date('0'+dispaly[6]);}    //百萬
  215.                 if(data_c>99999)        {        write_date('0'+dispaly[5]);}    //十萬
  216.                 if(data_c>9999)                {        write_date('0'+dispaly[4]);}    //萬
  217.                 if(data_c>999)                {        write_date('0'+dispaly[3]);}    //千
  218.                 if(data_c>99)                {        write_date('0'+dispaly[2]);}    //百
  219.                 if(data_c>9)                {        write_date('0'+dispaly[1]);}    //十
  220.                                                                 write_date('0'+dispaly[0]);    //個
  221.                 }
  222.         }
  223. //        else  //溢出時顯示錯誤
  224. //        {
  225. //                write_com(0x80+11+0x40); //第一行
  226. //                write_date('E');         //顯示 E
  227. //                write_date('r');         //顯示R
  228. //                write_date('r');                 //顯示R
  229. //                write_date('o');                 //顯示O
  230. //                write_date('r');                 //顯示E
  231. //        }
  232. }

  233. void eql(uchar x)//加減乘除運算
  234. {
  235.         switch(x)                /*功能鍵選擇*/
  236.                         {   
  237.                                 case 1:data_c=data_a+data_b;break;                   //加  /* + S=1 */ /* 數值轉換函數 */                                                                        
  238.                                 case 2:if(data_a>=data_b){data_c=data_a-data_b;} /* - S=2 *///減
  239.                        else{data_c=data_b-data_a;W_lcd(5,1,'-');} //負數符號
  240.                                            break;           
  241.                                 case 3:data_c=(data_a*data_b);break;                  /* * S=3 *///乘
  242.                                 case 4:if(data_b==0){LCD_Write_String(0,1,"Error !         ");}else{data_c=(data_a*10000)/data_b;}break;                  /* / S=4 *///除//溢出時顯示錯誤
  243.                                 case 0:break;
  244.                         }         

  245. }

  246. void main()
  247. {
  248.         uchar   key=0xff;               //鍵值初始化
  249.         uchar   n=0;                                         //第1個數可以按1-4次
  250.         uchar   m=5;                                         //第2個數可以按1-4次
  251.         uchar   x=0;
  252.         data_a=0;                       //前一個數
  253.         data_b=0;                       //后一個數
  254.         data_c=0;                       //結果
  255.         init_lcd();                                          //1602液晶初始化
  256.         display_a();
  257.           PX0=1; // 設置外部中斷 0 為高優先級
  258.           IT0=1;//跳變沿出發方式(下降沿)
  259.           IT1=1;//跳變沿出發方式(下降沿)
  260.                 EX0=1; // 允許外部中斷 0 打開
  261.                 EX1=1; // 允許外部中斷 1 打開
  262.                 EA=1; // 允許總中斷控制打開
  263.                  TMOD=0x66; // 設置定時 / 計數器中斷 0,擴展為外部中斷
  264.                 TH0=0xFF;
  265.                 TL0=0xFF;
  266.                 TCON=0x50;
  267.                 ET0=1;
  268.     while(1)
  269.           {
  270.                   key=keycheckdown();                        //動態掃描鍵盤,返回按鍵對應值,賦給j        key=0到f
  271.                 if(0xff!=key)                                //若返回值有效,進入內部處理程序
  272.                 {
  273.                   if(key<10)
  274.                   {
  275.                           if(key==0&&n==0) ;
  276.                         else
  277.                         {
  278.                                 if(n<4){data_a=data_a*10+key;m=5;display_a();}n++;  //首先輸入第一個數        
  279.                         }
  280.                 if(key==0&&m==0) ;
  281.                         else
  282.                         {
  283.                                 if(m<4){data_b=data_b*10+key;n=5;display_b();}m++;  //必須按了+-才能輸入第二個數        
  284.                         }
  285.                   }
  286.           else
  287.           {        switch(key)                /*功能鍵選擇*/
  288.                                         {
  289.                                                 case 0xa:n=5;m=0;x=1;W_lcd(5,0,'+');break; //加  /* + S=1 */ /* 數值轉換函數 */                                                                        
  290.                                                 case 0xb:n=5;m=0;x=2;W_lcd(5,0,'-');break;                  /* - S=2 *///減
  291.                                                 case 0xc:n=5;m=0;x=3;W_lcd(5,0,'*');break;                  /* * S=3 *///乘
  292.                                                 case 0xd:n=5;m=0;x=4;W_lcd(5,0,'/');break;                  /* / S=4 *///除
  293.                                                 case 0xe:n=5;m=5;eql(x);W_lcd(12,0,'=');display_c(x);break;           /* = */
  294.                                                 case 0xf:n=0;x=0;m=5; data_a=0;data_b=0;data_c=0;LCD_Write_String(0,0,table);LCD_Write_String(0,1,table);W_lcd(0,0,'0');break; /*     C*/
  295.                                         }                           
  296.                   }
  297.                         do{P1=0xf0;}while(P1!=0xf0);                /*等待按鍵松開*/
  298.                   }//(0xff!=key)         
  299.           }//while
  300. }//main

  301. void cshjs()    //計算器初始化
  302. {
  303. uchar   key=0xff;               //鍵值初始化
  304.         uchar   n=0;                                         //第1個數可以按1-4次
  305.         uchar   m=5;                                         //第2個數可以按1-4次
  306.         uchar   x=0;
  307.         data_a=0;                       //前一個數
  308.         data_b=0;                       //后一個數
  309.         data_c=0;                       //結果
  310.         init_lcd();                                          //1602液晶初始化
  311. }


  312. /*lcd滾動字幕控制程序部分*/

  313. /***************字幕水平滾動*************/
  314. void sp1()
  315. {
  316.         uint i,a;
  317.   write_com(0x00+0x80);
  318.         for(i=0;i<16;i++)
  319.         {
  320.                 write_date(a1[i]);
  321.         }
  322.         while(1){write_com(0x1c);
  323.                 a=keycheckdown();
  324.                 if((czs==0)||(a!=0xff)){cshjs();break;}
  325.         delay(200);}

  326. }
  327. /***************字幕垂直向上滾動*************/
  328. void cz()
  329. {
  330.           uint i,a;
  331.           write_com(0x01);
  332.                 write_com(0x80+0x00);
  333.                 for(i=0;i<16;i++)
  334.                 {
  335.                         write_date(a1[i]);
  336.                         a=keycheckdown();
  337.                         if((sp==0)||(a!=0xff)){cshjs();break;}
  338.                 }        
  339.                 delay(8);
  340.                 write_com(0x01);
  341.                 write_com(0x80+0x40);
  342.                 for(i=0;i<16;i++)
  343.                 {
  344.                         write_date(a1[i]);
  345.                         a=keycheckdown();
  346.                         if((sp==0)||(a!=0xff)){cshjs();break;}
  347.                 }
  348.                 delay(8);
  349. }


  350. /***************外部中斷 0,實現暫停P3^2口*************/

  351. void int0()interrupt 0 // 外部中斷 0,實現暫停
  352. {
  353.         EA=0; //關中斷
  354.         delay(10);
  355.          while(!stop);
  356.         EA=1;//開中斷

  357. }
  358. /***************外部中斷 1,實現垂直移動P3^3口*************/
  359. void int1()interrupt 2
  360. {
  361.         int a;
  362.         init_lcd();
  363.    while(1)
  364.         {
  365.                 cz();
  366.                 a=keycheckdown();
  367. if((sp==0)||(a!=0xff)){cshjs();break;}               
  368.         }        
  369. }
  370. /*************** 定時 / 計數器中斷擴展為外部中斷,實現水平移動P3^4口*************/
  371. void kt0()interrupt 1
  372. {
  373.         init_lcd();
  374.         sp1();                 
  375. }
復制代碼

所有資料51hei提供下載:
字幕滾動加計算器.zip (293.38 KB, 下載次數: 50)


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

使用道具 舉報

沙發
ID:697329 發表于 2020-3-3 04:17 | 只看該作者
有錯啊
回復

使用道具 舉報

板凳
ID:553020 發表于 2020-9-9 20:25 | 只看該作者

我實物都做出來了呀,可以正常使用呀
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 欧美日韩国产一区二区 | 亚洲高清在线观看 | www国产成人免费观看视频 | 81精品国产乱码久久久久久 | 99久久久国产精品 | 青青草视频网 | 国产永久免费 | 国产高清精品一区二区三区 | 亚洲高清视频一区 | 久久久爽爽爽美女图片 | 国产精品高潮呻吟久久 | 久久九精品 | 国产精品美女一区二区三区 | 99热国产精品 | 久久久久一区 | 日本久久一区二区三区 | 欧美日高清视频 | 日本久久精品视频 | 婷婷丁香综合网 | 好婷婷网 | 日本精品一区二区 | 亚洲欧美另类在线观看 | 亚洲欧美综合精品久久成人 | 国产高清视频一区 | 欧美精品电影一区 | 在线 丝袜 欧美 日韩 制服 | 国产一区精品 | www国产成人| 美女拍拍拍网站 | av免费网站在线观看 | 欧美a在线 | 欧美日韩成人影院 | 成人精品久久日伦片大全免费 | 国产一区二区精 | 黄色大片在线视频 | 黄色av一区 | 91精品国模一区二区三区 | 99热精品久久 | 国产精品国产成人国产三级 | 国产精品久久久久久久久久久久冷 | 久久国产精品久久久久久久久久 |