官术网_书友最值得收藏!

3.16 4×4鍵盤矩陣控制條形LED顯示

當(dāng)按鍵較多時(shí)會(huì)占用更多的控制器端口,為減少對(duì)端口的占用,本例使用4×4 鍵盤矩陣,這樣大大減少了端口占用,但識(shí)別按鍵的代碼比獨(dú)立按鍵的代碼要復(fù)雜一些。本例運(yùn)行過程時(shí)所點(diǎn)亮的LED個(gè)數(shù)與按鍵鍵值相等,例如,按下K1時(shí),第1只LED點(diǎn)亮,按下K2時(shí)前2只LED點(diǎn)亮,按下K10時(shí)第1~10只LED點(diǎn)亮。

本例電路及運(yùn)行效果如圖3-13所示。

圖3-13 4×4鍵盤矩陣控制條形LED顯示電路

程序設(shè)計(jì)調(diào)試與實(shí)訓(xùn):

本例鍵盤矩陣行線連接P0.0~P0.3,列線連接P0.4~P0.7,掃描過程如下:

程序首先判斷是否有鍵按下。為判斷16個(gè)按鍵中是否有鍵按下,程序首先在4條行線上放置4個(gè)0,即在P1端口輸出0xF0,如果有任一按鍵按下,則4條列線上必有一位為0。

如果已有鍵按下,則判斷按鍵所在行、列位置,并返回按鍵序號(hào)。代碼中行掃描碼sCode初值為0xFE(11111110),通過將該值循環(huán)右移,可對(duì)P1.0~P1.3對(duì)應(yīng)的4行逐行發(fā)送0,每次發(fā)送掃描碼后即判斷高4位的4個(gè)1中是否有0出現(xiàn),如果出現(xiàn)0則說明按鍵在該行上,這時(shí)可將發(fā)送的低4位與讀取的高4位取反,也就是P1取反,這樣P1中將出現(xiàn)2個(gè)1,其余位均變?yōu)?,2個(gè)1分別處在低4位和高4位中,高低4位中1所處的位置各有4種可能,共有16種可能,對(duì)應(yīng)16個(gè)不同按鍵,根據(jù)取反后的值查詢鍵盤矩陣按鍵特征碼表,即可得到按鍵序號(hào)。

另外,讀者要注意在代碼中用延時(shí)對(duì)按鍵進(jìn)行消抖。

讀者可將電路中的按鍵由縱向編號(hào)改為橫向編號(hào),重新修改代碼,看能否得到正確的運(yùn)行結(jié)果。

源程序代碼:

        //-----------------------------------------------------------------
        //  名稱: 4×4 鍵盤矩陣控制條形LED顯示
        //-----------------------------------------------------------------
        //  說明: 運(yùn)行本例時(shí),按下的按鍵鍵值越大,點(diǎn)亮的LED越多,例如,按下K1時(shí)
        //       點(diǎn)亮第1只LED,按下K2時(shí)點(diǎn)亮第1,2只LED,按下K16時(shí)全部LED點(diǎn)亮。
        //-----------------------------------------------------------------
        #include <reg51.h>
        #include <intrins.h>
        #define uchar unsigned char
        #define uint  unsigned int
        //0~9,A~F的數(shù)碼管段碼,最后一個(gè)是黑屏
        uchar code DSY_CODE[]=
        { 0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,
          0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0x00
        };
        //鍵盤矩陣按鍵特征碼表
        uchar code KeyCodeTable[] =
        {       0x11,0x12,0x14,0x18,0x21,0x22,0x24,0x28,0x41,0x42,0x44,0x48,0x81,0x82,
    0x84,0x88};
        //-----------------------------------------------------------------
        // 延時(shí)
        //-----------------------------------------------------------------
        void Delay()
        {
          uchar i;
          for(i = 0; i < 200; i++);
        }
        //-----------------------------------------------------------------
        // 鍵盤矩陣掃描
        //-----------------------------------------------------------------
        uchar Keys_Scan()
        {
            uchar sCode,kCode,i,k;
            //低4位置0,放入四行
            P1 = 0xF0;
            //如果高4位出現(xiàn)0則有鍵按下
            if ((P1 & 0xF0) != 0xF0)
            {
              Delay();
              if ((P1 & 0xF0) != 0xF0)
              {
                //行掃描碼初值
                sCode = 0xFE;
                //對(duì)4行分別進(jìn)行掃描
                for (k = 0; k < 4; k++)
                {
            P1 = sCode;
            if (( P1 & 0xF0) != 0xF0)
            {
                kCode = ~P1;
                //查表得到按鍵序號(hào)并返回
                for( i = 0; i< 16; i++)
                  if (kCode == KeyCodeTable[i]) return i;
            }
            else sCode = _crol_(sCode,1);
                }
              }
            }
            return -1;
        }
        //-----------------------------------------------------------------
        // 主程序
        //-----------------------------------------------------------------
        void main()
        {
          //按鍵序號(hào),-1表示無按鍵
          uchar KeyNo = -1;
          uchar i,P2_LED,P3_LED;
          while(1)
          {
            //掃描鍵盤獲取按鍵序號(hào)KeyNo
            KeyNo = Keys_Scan();
            if (KeyNo != -1)
            {
                P2_LED = 0xFF;
                P3_LED = 0xFF;
                //鍵值越大,點(diǎn)亮的LED越多
                for (i = 0; i <= KeyNo; i++)
                {
                  if ( i < 8)
            P3_LED >>= 1;
                  else
                      P2_LED >>= 1;
                }
                //點(diǎn)亮條形LED
                P3 = P3_LED;
                P2 = P2_LED;
            }
          }
        }
主站蜘蛛池模板: 泸州市| 武邑县| 专栏| 云林县| 论坛| 新野县| 东至县| 社会| 德钦县| 台中市| 综艺| 兴仁县| 门头沟区| 亳州市| 烟台市| 林州市| 遂宁市| 龙海市| 廊坊市| 祁门县| 彭水| 禄劝| 巍山| 永修县| 滦平县| 白城市| 庆元县| 高陵县| 沂南县| 长沙市| 志丹县| 公安县| 南陵县| 阳高县| 易门县| 门头沟区| 柳州市| 鹿泉市| 云和县| 横峰县| 麻江县|