找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開始

搜索
查看: 13940|回復(fù): 4
打印 上一主題 下一主題
收起左側(cè)

單片機(jī)講義12:矩陣按鍵

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:250285 發(fā)表于 2017-11-19 02:45 | 只看該作者 |只看大圖 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式
第12講 矩陣按鍵
知識(shí)點(diǎn):
1、 單片機(jī)程序的一般結(jié)構(gòu)
2、 keil 基本使用
3、 單片機(jī)識(shí)別按鍵的注意點(diǎn)
4、 識(shí)別矩陣按鍵的一種方法


一、單片機(jī)程序的一般結(jié)構(gòu)
1、前后臺(tái)結(jié)構(gòu) 前后臺(tái)結(jié)構(gòu)是最常用的結(jié)構(gòu)。所謂前后臺(tái)結(jié)構(gòu)就是主循環(huán)+中斷的方式,主
循環(huán)稱為后臺(tái),前臺(tái)就是中斷程序。主循環(huán)用 while(1)或其它死循環(huán)結(jié)構(gòu)輪詢
任務(wù),而前臺(tái)負(fù)責(zé)處理實(shí)時(shí)性要求較高的任務(wù),或者外部中斷任務(wù),一般把按鍵 掃描、顯示掃描放在定時(shí)中斷里。
2、占用式程序與非占用式程序
凡是用 while、for 等循環(huán)語句實(shí)現(xiàn)的程序都稱為占用式程序。占用式程序的特 點(diǎn)是 CPU 必須執(zhí)行完所有的循環(huán)任務(wù)才能退出,除非有中斷發(fā)生,比如我們做的 獨(dú)立按鍵處理程序就是占用式程序。在單片機(jī)程序設(shè)計(jì)中要盡量避免設(shè)計(jì)占用式 程序。與其相對(duì)應(yīng)的是非占用式程序,非占用式程序能提高 CPU 的使用效率,讓 所有的任務(wù)都能及時(shí)得到響應(yīng)。
二、keil 基本使用
1、點(diǎn)擊工程文件圖標(biāo),進(jìn)入源代碼編輯區(qū)。
2、保存、編譯、生成 hex 文件
3、下載、運(yùn)行

三、單片機(jī)識(shí)別按鍵的注意點(diǎn)
識(shí)別哪個(gè)鍵被按下(通過讀取鍵碼的方式)、識(shí)別按鍵所處的狀態(tài)(有效方 式),常用的有效方式:抬起有效、按下有效、組合有效、長(zhǎng)按有效等

四、識(shí)別矩陣按鍵的一種方法
矩陣式按鍵接法,是利用單片機(jī)的IO 口組成行與列,在行與列的每一個(gè) 交點(diǎn)處連接按鍵。故也稱為矩陣式按鍵。電路結(jié)構(gòu)如下所示:
file:///Z:/TEMP/msohtmlclip1/01/clip_image002.jpg
這種按鍵的識(shí)別方法,我們會(huì)在第 5 個(gè)知識(shí)點(diǎn)上詳細(xì)講解。


五、單片機(jī)識(shí)別按鍵的一般思路:

一般情況下,單片機(jī)識(shí)別按鍵的目的是識(shí)別當(dāng)前按鍵的狀態(tài),意 思就是說,一要識(shí)別是哪個(gè)鍵動(dòng)作了(鍵碼),還要識(shí)別當(dāng)前按鍵 是何狀態(tài),也稱為有效方式,當(dāng)然了這里的狀態(tài)大多是與時(shí)間有關(guān)的,并執(zhí)行相應(yīng)的動(dòng)作。比如,開發(fā)板上獨(dú)立式按鍵實(shí)驗(yàn),當(dāng)按鍵

按下并抬起時(shí),LED 被點(diǎn)亮。這是最簡(jiǎn)單的識(shí)別。因?yàn)槭且恢О存I,所以不用識(shí)別是哪個(gè)鍵被按下,只需識(shí)別按鍵的狀態(tài)。一般的按鍵 狀態(tài)有以下幾種:按下,抬起,長(zhǎng)按,組合,長(zhǎng)按多長(zhǎng)時(shí)間等等。

一個(gè)完整的按鍵動(dòng)作必須包含下面四個(gè)階段: 按鍵按下-à按下消抖-à按鍵抬起-à抬起消抖 在單片機(jī)與按鍵接口程序中,往往先進(jìn)行按下消抖,而對(duì)按鍵狀態(tài)的 判斷就是指按鍵處理了。這里的按鍵處理不是執(zhí)行相應(yīng)的動(dòng)作,而是 區(qū)分按鍵此刻處于何種狀態(tài),并改變相應(yīng)狀態(tài)變量的值,以便程序其 它地方通過檢測(cè)相應(yīng)的按鍵狀態(tài)變量去執(zhí)行相應(yīng)的動(dòng)作。比如,我們可以把按下并抬起的短按點(diǎn)亮 LED,改成長(zhǎng)按一段時(shí)間點(diǎn)亮 LED?偟膩碇v,單片機(jī)識(shí)別按鍵就分為三個(gè)階段:按鍵消抖---按鍵處理---


按鍵執(zhí)行。這個(gè)思路適用于所有形式的按鍵。至于為什么要消抖?是 因?yàn)槲覀冊(cè)诓僮靼存I時(shí),不可能立即按下或抬起,機(jī)械式按鍵接觸面 不是立刻就接觸或斷開的,而單片機(jī)的檢測(cè)速度特別快,這樣往往會(huì) 發(fā)生誤判,因此,我們要等待電平穩(wěn)定了,再去處理按鍵。消抖的方 式很簡(jiǎn)單,就是利用延時(shí),等待一個(gè)穩(wěn)定電平的到來。

六、識(shí)別行列式按鍵的一種方法
H:表示行;L:表示列;


  L0 P13
  L1 P12
  L2 P11
  L3 P10
   
  H0  P17
  0
  1
  2
  3
   
  H1  P16
  4
  5
  6
  7
   
  H2  P15
  8
  9
  10
  11
   
  H3  P14
  12
  13
  14
  15
   






我們先測(cè)試列,測(cè)試列時(shí),把行控 IO 設(shè)置為 0,列空IO 設(shè)置為 1
即:P1 = 0X0F;此時(shí)若有按鍵被按下,我們可以得到 4 組編碼:
0X07,0X0B,0X0D,0X0E;每一組又對(duì)應(yīng)列的四個(gè)按鍵。然后我們?cè)贉y(cè)試行:P1 = 0XF0;又可以得出四個(gè)按鍵編碼,這樣就可以判斷是哪個(gè)鍵被按下了。這里依然是抬起有效。




這是以前給小學(xué)生培訓(xùn)單片機(jī)做的一套講義,盡可能的做到了通俗易懂,現(xiàn)分享給大家,絕對(duì)的純?cè)瓌?chuàng)資料.
全部資料下載地址(共15章,pdf格式):http://www.torrancerestoration.com/bbs/dpj-98524-1.html









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

使用道具 舉報(bào)

沙發(fā)
ID:435312 發(fā)表于 2018-12-2 19:01 | 只看該作者
學(xué)習(xí)一下
回復(fù)

使用道具 舉報(bào)

板凳
ID:508017 發(fā)表于 2019-5-11 19:56 | 只看該作者
給小學(xué)生培訓(xùn)的,,慚愧啊
回復(fù)

使用道具 舉報(bào)

地板
ID:887908 發(fā)表于 2021-3-3 09:50 | 只看該作者
怎樣下載學(xué)習(xí)一下呢?
回復(fù)

使用道具 舉報(bào)

5#
ID:1017814 發(fā)表于 2022-4-16 15:02 | 只看該作者
我的按鍵掃描程序如下,講老大們給于評(píng)判。
unsigned char key_scan()
{
        hang1=0;
        hang2=1;
        hang3=1;
        hang4=1;
        if(lie1==0)                                //right         15
        {
                 key_delay();
                if(lie1==0)
                {
                   return 'R'+'\0';
                }
                while(lie1==0);
        }
        if(lie2==0)                                   //up                14
        {
                 key_delay();
                if(lie2==0)
                {
                   return 'U'+'\0';
                }
                while(lie2==0);
        }
        if(lie3==0)                                //down           13
        {
                 key_delay();
                if(lie3==0)
                {
                   return 'D'+'\0';
                }
                while(lie3==0);
        }
        if(lie4==0)                                        //left           12
        {
                 key_delay();
                if(lie4==0)
                {
                   return 'L'+'\0';
                }
                while(lie4==0);
        }
        hang1=1;
        hang2=0;
        hang3=1;
        hang4=1;
        if(lie1==0)                                //ok
        {
                 key_delay();
                if(lie1==0)
                {
                   return 'Y'+'\0';
                }
                while(lie1==0);
        }
        if(lie2==0)                                   //9
        {
                 key_delay();
                if(lie2==0)
                {
                   return 9;
                }
                while(lie2==0);
        }
        if(lie3==0)                                //3
        {
                 key_delay();
                if(lie3==0)
                {
                   return 3;
                }
                while(lie3==0);
        }
        if(lie4==0)                                        //6
        {
                 key_delay();
                if(lie4==0)
                {
                   return 6;
                }
                while(lie4==0);
        }
        hang1=1;
        hang2=1;
        hang3=0;
        hang4=1;
        if(lie1==0)                                //0
        {
                 key_delay();
                if(lie1==0)
                {
                   return 0;
                }
                while(lie1==0);
        }
        if(lie2==0)                                   //8
        {
                 key_delay();
                if(lie2==0)
                {
                   return 8;
                }
                while(lie2==0);
        }
        if(lie3==0)                                //2
        {
                 key_delay();
                if(lie3==0)
                {
                   return 2;
                }
                while(lie3==0);
        }
        if(lie4==0)                                        //5
        {
                 key_delay();
                if(lie4==0)
                {
                   return 5;
                }
                while(lie4==0);
        }
        hang1=1;
        hang2=1;
        hang3=1;
        hang4=0;
        if(lie1==0)                                //ESC
        {
                 key_delay();
                if(lie1==0)
                {
                   return 'N'+'\0';
                }
                while(lie1==0);
        }
        if(lie2==0)                                   //7
        {
                 key_delay();
                if(lie2==0)
                {
                   return 7;
                }
                while(lie2==0);
        }
        if(lie3==0)                                //1
        {
                 key_delay();
                if(lie3==0)
                {
                   return 1;
                }
                while(lie3==0);
        }
        if(lie4==0)                                        //4
        {
                 key_delay();
                if(lie4==0)
                {
                   return 4;
                }
                while(lie4==0);
        }
        return 0xff;                   
}
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

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

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表