<acronym id="xonnx"></acronym>
      <td id="xonnx"></td>
    1. <pre id="xonnx"></pre>

      1. 專注電子技術學習與研究
        當前位置:單片機教程網 >> MCU設計實例 >> 瀏覽文章

        基于51單片機的簡易計算器1602顯示

        作者:我行天下   來源:本站原創   點擊數:  更新時間:2014年03月30日   【字體:

        /*注:4 X4 矩陣接P3口*/
        #include<reg52.h>
        #include<stdio.h>
        #include<intrins.h>
        #define uchar  unsigned char 
        #define uint  unsigned int
        #define CHECK_BUSY
        sbit RS = P2^4;
        sbit RW = P2^5;
        sbit EN = P2^6;
        void DelayMs(int z)
        {
         int x,y;
         for (x=z;x>0;x--)
           for(y=110;y>0;y--);
        }
        /***********判忙函數***********/
         bit LCD_Check_Busy()
         {
        #ifdef CHECK_BUSY
         P0= 0xFF;
         RS=0;
         RW=1;
         EN=0;
         _nop_();
         EN=1;
         return (bit)(P0 & 0x80);
        #else
         return 0;
        #endif
         }
        /***********寫入命令函數***********/
         void write_com(uchar com)
         {
        while(LCD_Check_Busy()); //忙則等待
         RS=0;
         RW=0;
         EN=1;
         P0= com;
         _nop_();
         EN=0;
         }
        /**********寫入數據函數**********/
         void write_dat(uchar dat)
         {
         while(LCD_Check_Busy()); //忙則等待
         RS=1;
         RW=0;
         EN=1;
         P0= dat;
         _nop_();
         EN=0;
         }
        /*******寫入字符函數***********/
        void LCD_Write_Char(uchar x,uchar y,uchar dat)
         {   
         if (y == 0)
          {   
          write_com(0x80 + x);   
          }  
         else
          {   
          write_com(0xC0 + x);   
          }      
         write_dat( dat);
         }
        /******寫入字符串函數***********/
         void Write_String(uchar x,uchar y,uchar *s)
         {   
             
         while (*s)
          {   
          LCD_Write_Char(x,y,*s);   
          s++;
          x++;   
          }
         }
        /*****初始化函數******/
         void LCD_Init()
         {
           write_com(0x38); /*顯示模式設置*/
           DelayMs(5);
           write_com(0x06);/*顯示光標移動設置*/
           DelayMs(5);
           write_com(0x0C); /*顯示開及光標設置*/
           write_com(0x01);  /*顯示清屏*/
           }
         
        /*按鍵掃描函數,返回掃描鍵值*/
        uchar KeyScan()  //鍵盤掃描函數,使用行列反轉掃描法
        {
         unsigned char cord_h,cord_l;//行列值中間變量
         P3=0x0f;            //行線輸出全為0
         cord_h=P3&0x0f;     //讀入列線值
         if(cord_h!=0x0f)    //先檢測有無按鍵按下
         {
          DelayMs(10);        //去抖
          if((P3&0x0f)!=0x0f)
          {
            cord_h=P3&0x0f;  //讀入列線值
            P3=cord_h|0xf0;  //輸出當前列線值
            cord_l=P3&0xf0;  //讀入行線值
            while((P3&0xf0)!=0xf0);//等待松開并輸出
            return(cord_h+cord_l);//鍵盤最后組合碼值
           }
          }
          return(0xff);  //返回該值
        }

        unsigned char KeyPro()
        {
         switch(KeyScan())
         {
          case 0x7e:return '1';break;//0 按下相應的鍵顯示相對應的碼值
          case 0x7d:return '2';break;//1
          case 0x7b:return '3';break;//2
          case 0x77:return '+';break;//3
          case 0xbe:return '4';break;//4
          case 0xbd:return '5';break;//5
          case 0xbb:return '6';break;//6
          case 0xb7:return '-';break;//7
          case 0xde:return '7';break;//8
          case 0xdd:return '8';break;//9
          case 0xdb:return '9';break;//a
          case 0xd7:return 'x';break;//b
          case 0xee:return '0';break;//c
          case 0xed:return '.';break;//d
          case 0xeb:return '=';break;//e
          case 0xe7:return '/';break;//f
          default:return 0xff;break;
         }
        }
        main()
        {
         unsigned char num,i,sign;                
         unsigned char temp[16];   //最大輸入16個
         bit firstflag;
         float a=0,b=0;
         unsigned char s;
         LCD_Init(); //初始化液晶屏
         DelayMs(10);//延時用于穩定,可以去掉
         write_com(0x01); //清屏
         Write_String(0,0,"I LIKE MCU");    //寫入第一行信息,主循環中不再更改此信息,所以在while之前寫入
         Write_String(0,1,"HBKJXY");    //寫入第二行信息,提示輸入密碼
         for(s=0;s<25;s++)//延時5s
            DelayMs(200);
         write_com(0x01);
        while (1)         //主循環
          {

         num=KeyPro();  //掃描鍵盤
         if(num!=0xff)  //如果掃描是按鍵有效值則進行處理
           {
            if(i==0)    //輸入是第一個字符的時候需要把改行清空,方便觀看
           write_com(0x01);
         if(('+'==num)|| (i==16) || ('-'==num) || ('x'==num)|| ('/'==num) || ('='==num))//輸入數字最大值16,輸入符號表示輸入結束
           {
           i=0;  //計數器復位
          if(firstflag==0)  //如果是輸入的第一個數據,賦值給a,并把標志位置1,到下一個數據輸入時可以跳轉賦值給b
              {
              sscanf(temp,"%f",&a);
                 firstflag=1;
           }
           else
              sscanf(temp,"%f",&b);
           for(s=0;s<16;s++) //賦值完成后把緩沖區清零,防止下次輸入影響結果
              temp[s]=0;
              LCD_Write_Char(0,1,num);
           ///////////////////////
           if(num!='=')      //判斷當前符號位并做相應處理
              sign=num;      //如果不是等號記下標志位
           else
              {
           firstflag=0;   //檢測到輸入=號,判斷上次讀入的符合
                 switch(sign)
                {
              case '+':a=a+b;
           break;
           case '-':a=a-b;
           break;
           case 'x':a=a*b;
           break;
           case '/':a=a/b;
           break;
           default:break;
             }
           sprintf(temp,"%g",a);    //輸出浮點型,無用的0不輸出
                 Write_String(1,1,temp);//顯示到液晶屏
           sign=0;a=b=0;            //用完后所有數據清零
           for(s=0;s<16;s++)
              temp[s]=0;
           }
           }
          else if(i<16)
           {
            if((1==i)&& (temp[0]=='0') )//如果第一個字符是0,判讀第二個字符
              {
            if(num=='.')  //如果是小數點則正常輸入,光標位置加1
              {
              temp[1]='.';
           LCD_Write_Char(1,0,num);//輸出數據
           i++;
                    } //這里沒有判斷連續按小數點,如0.0.0
           else
            {
             temp[0]=num; //如果是1-9數字,說明0沒有用,則直接替換第一位0
             LCD_Write_Char(0,0,num);//輸出數據
             }
           }
            else
              {
                 temp[i]=num;
                 LCD_Write_Char(i,0,num);//輸出數據
              i++;   //輸入數值累加
           }
            }
         
            }
          }
        }

        關閉窗口

        相關文章

        欧美性色欧美精品视频,99热这里只有精品mp4,日韩高清亚洲日韩精品一区二区,2020国自产拍精品高潮