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

    基于51單片機開發之鍵盤

    作者:佚名   來源:本站原創   點擊數:  更新時間:2014年04月19日   【字體:

    1、鍵盤分類

         鍵盤分編碼鍵盤和非編碼鍵盤,鍵盤上閉合鍵的識別由專用的硬件編碼器實現,并產生鍵編碼或鍵值的稱為編碼鍵盤,如計算機鍵盤。

    • 而靠軟件編程來識別的稱為非編碼鍵盤;
    • 在單片機組成的各種系統中,用的最多的是非編碼鍵盤。也有用到編碼鍵盤的。
    • 非編碼鍵盤又分為:獨立鍵盤和行列式(又稱為矩陣式)鍵盤。
                                此圖為矩陣鍵盤



                         此圖為獨立鍵盤

    • 在單片機內部P1,P2,P3口各I/O口線片內均有固定的上拉電阻,當這3個準雙向I/O口作為輸入口使用時,向該口先寫“1”   才能讀取這個I/O的狀態,P3.4 =1 ,如果這個I/O口沒有3態就是沒有3態關系這個I/O就跟連接的元器件是一個線與的關系,所以按鍵按下去就是低電平。如果有3態的I/O口就是跟連接的器件是一個線或的關系,高阻態并非是高電平還是低電平,而是高阻狀態,如果外接高它就是高,接低它就是低電平。
    • 實例:先寫個程序檢測下吧

    note:說明下這個程序就是每按下按鍵讓一個數碼管變一下,從0--9 然后再按變成0循環

    #include

    #define uchar unsigned char

    sbit  d1= P1^0; //這個腳接的是發光二極管。

    sbit key1= P3^4 ;//接的一個按鍵

    sbit dula = P2^6;// 段啦   控制數碼管 

    sbit wela = P^7;// 位啦   控制數碼管

    uchar num;

     

    uchar code table[]={
    0x3f,0x06,0x5b,0x4f,
    0x66,0x6d,0x7d,0x07,
    0x7f,0x6f,0x77,0x7c,
    0x39,0x5e,0x79,0x71,
    0x76,0x79,0x38,0x3f,0};//編碼表 數組 code 是在ROM區

    void main(){

      wela =1;

      P0= Oxfe;

      wela=0;   //位選就打開一個數碼管的 

        

      P3 = 0XFF;  //把P3都給寫1

       while(1){   //輪循的方式

            if(0==key1){

                d1= 0; //點亮燈

                num ++;//每按一次按鍵讓num++

                if (10==num)

                     num=0; //一個數碼管就只能顯示9

             

           }else {

             d1 = 1; //熄滅燈

            }

          dula =1;

          P0 = table[num];

          dula =0;

       }

     

    以上程序存在問題:按下按鍵時候數碼管顯示的不是1 2.....9 0 1...  原因是:你按下的大概低電平持續了20毫秒,20毫秒此程序執行了多少次了,所以數碼管顯示的不是1 可能是5 可能是8 9 。所以必須做一個松手檢測。

    #include

    #define uchar unsigned char

    sbit  d1= P1^0; //這個腳接的是發光二極管。

    sbit key1= P3^4 ;//接的一個按鍵

    sbit dula = P2^6;// 段啦   控制數碼管 

    sbit wela = P^7;// 位啦   控制數碼管

    uchar num;

     

    uchar code table[]={
    0x3f,0x06,0x5b,0x4f,
    0x66,0x6d,0x7d,0x07,
    0x7f,0x6f,0x77,0x7c,
    0x39,0x5e,0x79,0x71,
    0x76,0x79,0x38,0x3f,0};//編碼表 數組 code 是在ROM區

    void main(){

      wela =1;

      P0= Oxfe;

      wela=0;   //位選就打開一個數碼管的 

        

      P3 = 0XFF;  //把P3都給寫1

       while(1){   //輪循的方式

            if(0==key1){

                d1= 0; //點亮燈

                num ++;//每按一次按鍵讓num++

                if (10==num)

                     num=0; //一個數碼管就只能顯示9

                while (!key1)  //松手檢測  只要你按鍵按下去是0 取反 一直等待 否則跳出去到下面

           }else {

             d1 = 1; //熄滅燈

     

            }

          dula =1;

          P0 = table[num];

          dula =0;

       }

     以上程序雖然得到改善,但是存在按一下會加得不是1現象,當然幾率不大,但確實存在。

    • 按鍵在閉合和斷開時,觸點會存在抖動現象

      

     


          從這個圖看按下和松開有毛刺                            這個是硬件消抖動不要理解
    我們解決的是按下去的毛刺去掉:延時函數 10毫秒   也就是說我們第一次按下去的時候我們延時個10毫秒,實際上毛刺抖動為5毫秒左右,我們給10毫秒更穩定。程序如下:

     

    #include

    #define uchar unsigned char

    sbit  d1= P1^0; //這個腳接的是發光二極管。

    sbit key1= P3^4 ;//接的一個按鍵

    sbit dula = P2^6;// 段啦   控制數碼管 

    sbit wela = P^7;// 位啦   控制數碼管

    uchar num;

     

    uchar code table[]={
    0x3f,0x06,0x5b,0x4f,
    0x66,0x6d,0x7d,0x07,
    0x7f,0x6f,0x77,0x7c,
    0x39,0x5e,0x79,0x71,
    0x76,0x79,0x38,0x3f,0};//編碼表 數組 code 是在ROM區

    //此為延時 測試值為1毫秒級

    void delay(uint z)
    {
     uint t1,y;
     for(t1=z;t1>0;t1--)
      for(y=110;y>0;y--);
    }

     

    void main(){

      wela =1;

      P0= Oxfe;

      wela=0;   //位選就打開一個數碼管的 

        

      P3 = 0XFF;  //把P3都給寫1

       while(1){   //輪循的方式

            if(0==key1){

                delay(10);//延時10毫秒

                if (0==key1){  //再確認下確實按下去了多了delay  和if 判斷

                d1= 0; //點亮燈

                num ++;//每按一次按鍵讓num++

                if (10==num)

                     num=0; //一個數碼管就只能顯示9

                }

                while (!key1)  //松手檢測  只要你按鍵按下去是0 取反 一直等待 否則跳出去到下面

           }else {

             d1 = 1; //熄滅燈

     

            }

          dula =1;

          P0 = table[num];

          dula =0;

       }

    經過以上的更改是改善了問題但是還是會存在抖動現象,原因是我們只是在按下去消除抖動,沒有在松手消除抖動,但是實際的項目中一般我們都是按下去的時候做消除抖動,如果想要達到更好的效果可以在松手也做消除抖動。程序簡單修改如下:

    #include

    #define uchar unsigned char

    sbit  d1= P1^0; //這個腳接的是發光二極管。

    sbit key1= P3^4 ;//接的一個按鍵

    sbit dula = P2^6;// 段啦   控制數碼管 

    sbit wela = P^7;// 位啦   控制數碼管

    uchar num;

     

    uchar code table[]={
    0x3f,0x06,0x5b,0x4f,
    0x66,0x6d,0x7d,0x07,
    0x7f,0x6f,0x77,0x7c,
    0x39,0x5e,0x79,0x71,
    0x76,0x79,0x38,0x3f,0};//編碼表 數組 code 是在ROM區

    //此為延時 測試值為1毫秒級

    void delay(uint z)
    {
     uint t1,y;
     for(t1=z;t1>0;t1--)
      for(y=110;y>0;y--);
    }

     

    void main(){

      wela =1;

      P0= Oxfe;

      wela=0;   //位選就打開一個數碼管的 

        

      P3 = 0XFF;  //把P3都給寫1

       while(1){   //輪循的方式

            if(0==key1){

                delay(10);//延時10毫秒

                if (0==key1){  //再確認下確實按下去了多了delay  和if 判斷

                d1= 0; //點亮燈

                num ++;//每按一次按鍵讓num++

                if (10==num)

                     num=0; //一個數碼管就只能顯示9

                }

                while (!key1)  //松手檢測  只要你按鍵按下去是0 取反 一直等待 否則跳出去到下面

                dely(10);    //松手消除抖動  就是延時

               while(!key1);// 再確認下 然后執行下面語句

       

           }else {

             d1 = 1; //熄滅燈

     

            }

          dula =1;

          P0 = table[num];

          dula =0;

       }

     

    以上程序是獨立鍵盤的應用中確實存在的一些問題和本人的一些簡單的解決問題的思路。當然延時也可以改成5毫秒盡量的不要讓MCU過多的等待。一般的項目中都不會采用延時來去抖動,可以用定時器來去除抖動。特別在一些嵌入式系統中常用定時器去抖動,因為嵌入式設備的硬件資源太寶貴了哦。希望大牛們給個定時器的去除抖動程序。。。!

    關閉窗口

    相關文章

    亚洲一区二区制服在线|在绩专区欧美自拍日韩|青春娱乐网97超碰人人射|在线观看国产网址你懂的