51單片機、獨立按鍵的認識與編程

一、基本知識

1. 按鍵分類與輸入原理

按鍵按照結構原理科分為兩類,一類是觸點式開關按鍵,如機械式開關、導電橡膠式開關燈;另一類是無觸點式開關按鍵,如電氣式按鍵,磁感應按鍵等。前者造價低,后者壽命長。目前,微機系統中最常見的是觸點式開關按鍵。

在單片機應用系統中,除了復位按鍵有專門的復位電路及專一的復位功能外,其他按鍵都是以開關狀態來設置控制功能或輸入數據的。當所設置的功能鍵或數字鍵按下時,計算機應用系統應完成該按鍵所設定的功能,鍵信息輸入時與軟件結構密切相關的過程。

對于一組鍵或一個鍵盤,總有一個接口電路與CPU相連。CPU可以采用查詢或中斷方式了解有無將按鍵輸入,并檢查是哪一個按鍵按下,將該鍵號送入累加器,然后通過跳轉指令轉入執行該鍵的功能程序,執行完成后再返回主程序。

2. 按鍵結構與特點

微機鍵盤通常使用機械觸點式按鍵開關,其主要功能式把機械上的通斷轉換為電氣上的邏輯關系。也就是說,它能提供標準的TTL邏輯電平,以便于通用數字系統的邏輯電平相容。機械式按鍵再按下或釋放時,由于機械彈性作用的影響,通常伴隨有一定的時間觸點機械抖動,然后其觸點才穩定下來。

圖1-按鍵抖動

其抖動過程如圖1所示,抖動時間的長短與開關的機械特性有關,一般為5-10ms。在觸點抖動期間檢測按鍵的通與斷,可能導致判斷出錯,即按鍵一次按下或釋放錯誤的被認為是多次操作,這種情況是不允許出現的。為了克服按鍵觸點機械抖動所致的檢測誤判,必須采取消抖措施。按鍵較少時,可采用硬件消抖;按鍵較多式,采用軟件消抖。

3. 獨立按鍵與矩陣鍵盤

(1)獨立按鍵

單片機控制系統中,如果只需要幾個功能鍵,此時,可采用獨立式按鍵結構。

獨立按鍵式直接用I/O口線構成的單個按鍵電路,其特點式每個按鍵單獨占用一根I/O口線,每個按鍵的工作不會影響其他I/O口線的狀態。獨立按鍵的典型應用如圖所示。獨立式按鍵電路配置靈活,軟件結構簡單,但每個按鍵必須占用一個I/O口線,因此,在按鍵較多時,I/O口線浪費較大,不宜采用。獨立按鍵如圖2所示。

圖2-獨立按鍵

獨立按鍵的軟件常采用查詢式結構。先逐位查詢與I/O口線的輸入狀態,如某一根I/O口線輸入為低電平,則可確認該I/O口線所對應的按鍵已按下,然后,再轉向該鍵的功能處理程序。

(2) 關于上拉電阻

單片機按鍵一般通過配備上拉電阻來實現輸入端高低電平的切換。

圖3-上拉電阻

4條輸入線接到單片機的IO口上,當按鍵K1按下時,+5V通過電阻R1然后再通過按鍵K1最終進入GND形成一條通路,那么這條線路的全部電壓都加到了R1這個電阻上,KeyIn1這個引腳就是個低電平。當松開按鍵后,線路斷開,就不會有電流通過,那么KeyIn1和+5V就應該是等電位,是一個高電平。我們就可以通過KeyIn1這個IO口的高低電平來判斷是否有按鍵按下。

三、獨立按鍵實例編程

1.說明

以普中科技51單片機開發板為例

圖4為獨立按鍵電路圖 8個按鍵分別對應JP5的八個引腳,所有按鍵統一接地,按鍵之間互不影響,JP5中包含上拉電阻。當按鍵松開時,對應引腳輸入1;當按鍵按下時,對應引腳輸入0。

圖5為流水燈電路圖 8個LED燈接地共陰,當引腳輸出1時,LED燈亮;當引腳輸出0時,LED燈滅。

圖4-獨立按鍵
圖5-流水燈

2.代碼實現

(1) 無消抖的8個引腳控制8個LED燈
#include <reg51.h>
#define Key P0    //P0接獨立按鍵電路引腳
#define Led P2    //P2接LED流水燈電路引腳
int main()
{
    unsigned char i;
    P2=0x00;    //初始化流水燈全滅
    
    while(1)
    {
        //動態掃描八個按鍵
        for(i=0;i<8;i++)
        {
            if( 0 == (Key&(1<<i)) ) Led|=1<<i;    //按鍵按下
            else Led&=~(1<<i);    //按鍵彈起
        }
    }
    return 0;
}

(2) 通過按鍵控制單個數碼管計數并作消抖處理

具體要求:
  • 數碼管初始化為0,按下按鍵增加對應的數,例如按下Key1則增加1,按下Key2則增加2
  • Key8用于清零
  • 超出9時,要做越界處理
  • 消抖
  • 按鍵抬起檢測 按一次只加一次
//printNum.h頭文件
#define Led P2     //P2口控制單個數碼管
#define state 1    //此處是共陽數碼管 所以置1
void printNum(int i)
{
    //0123456789AbCDEF
    unsigned char num[16]={0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90, 0x88, 0x83, 0xc6, 0xa1, 0x86, 0x8e};
    if(state==1) Led=num[i];        //Common yang
    else Led=~num[i];       //Common yin
}
void delay_ms(unsigned int i)
{
    unsigned int temp=i*100;
    while(temp--) ;
}
#include <reg51.h>
#include "printNum.h"
#define Key P0

int main()
{
    unsigned char i;
    unsigned char count=0;
    while(1)
    {
        printNum(count);
        for(i=0;i<7;i++)    //動態檢測8個按鍵
        {
            if( 0==(Key&(1<<i)) )       //判斷按鍵是否按下 
            {
                delay_ms(150);          //消抖
                if( 0==(Key&(1<<i)) )   
                    count+=i+1;         //累加上對應的數
                
                if(count>9) count%=10;  //防止越界
                
                printNum(count);        //實時更新數字
                while( !(Key&(1<<i)) ) ;  //按鍵抬起檢測
            }
        }   
        if( 0 == (Key&(1<<7))) count=0;  //最后一個鍵用于清零
    }
}

(3)通過按鍵控制多個數碼管計數

具體要求:
  • 功能:數碼管初始化為0,按下按鍵增加對應的數,例如按下Key1則增加1,按下Key2則增加2……但是按下Key8需清零
  • 使用38譯碼器對COM口進行控制 節省I/O口
  • P1的三個引腳控制38譯碼器,其他引腳上的值不允許被改動
  • P2控制數碼管段碼端的給值
  • P0控制檢測按鍵的輸入
  • 按鍵要消抖 抬起要檢測 邊界要檢測
#define Led P2
#define state 0
void printNum(int i)
{
    //0123456789AbCDEF
    unsigned char num[16]={0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90, 0x88, 0x83, 0xc6, 0xa1, 0x86, 0x8e};
    if(state==1) Led=num[i];        //Common yang
    else Led=~num[i];       //Common yin
}
void delay_ms(unsigned int i)
{
    unsigned int temp=i*100;
    while(temp--) ;
}
#include <reg51.h>
#include "printNum.h"
#define Key P0
#define LED_PLACE P1

unsigned char screenNum[8]={0,0,0,0,0,0,0,0};

int main()
{
    
    unsigned char i;
    unsigned char j;
    unsigned long count=0;
    unsigned long temp=0;
    while(1)
    {
        LED_PLACE &= 0xf8;  //Clear PLACE.0-2
        if(count>99999999) count=0;     //deal with the range
        temp=count;
        for(i=0;i<8;i++)    //transfer long to arr
        {
            screenNum[7-i]=temp%10;
            temp/=10;
        }       
        for(i=0;i<8;i++)    //give nums to screen
        {
            printNum(screenNum[i]);
            j=100; 
            while(j--) ;
            Led = 0x0;      //remove the double image
            LED_PLACE+=1;   //control the place
        }
        
        for(i=0;i<7;i++)      //scan the press keys
        {
            if( 0==(Key&(1<<i)) ) 
            {
                delay_ms(150);
                if( 0==(Key&(1<<i)) )   
                    count+=i+1;
                
                while( !(Key&(1<<i)) ) ;
            }
        }   
        if( 0 == (Key&(1<<7))) count=0;    //key8 to clear all
        
    }
}

不足:按下按鍵時,數碼管全部熄滅,這是由于掉進按鍵檢測的死循環中,無法掃描動態數碼管。改進方法,等待學習中斷和定時器。

實驗現象

更新:

(3) 通過中斷來控制按鈕增加數碼管顯示

連線方式:

  • P2接J12控制動態數碼管段碼端
  • P1.0-2接J6-三八譯碼器 控制動態數碼管COM端
  • P3.2接JP5-K1 INT0控制按鍵1
#define Led P2
#define state 0
void printNum(int i)
{
    //0123456789AbCDEF
    unsigned char num[16]={0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90, 0x88, 0x83, 0xc6, 0xa1, 0x86, 0x8e};
    if(state==1) Led=num[i];        //Common yang
    else Led=~num[i];       //Common yin
}
void delay_ms(unsigned int i)
{
    unsigned int temp=i*100;
    while(temp--) ;
}
#include <reg51.h>
#include "printNum.h"
#define LED_PLACE P1

unsigned char screenNum[8]={0,0,0,0,0,0,0,0};
unsigned long count=0;

void exint0() interrupt 0   // P3.2
{
    count++;
}

void initDevice()
{
    IT0=1;
    EX0=1;
    EA=1;
}
int main()
{
    
    unsigned char i;
    unsigned char j;
    
    unsigned long temp=0;
    
    initDevice();
    
    while(1)
    {
        LED_PLACE &= 0xf8;  //Clear PLACE.0-2
        if(count>99999999) count=0;     //deal with the range of dital
        temp=count;
        for(i=0;i<8;i++)    //transfer long to arr
        {
            screenNum[7-i]=temp%10;
            temp/=10;
        }       
        for(i=0;i<8;i++)    //give nums to screen
        {
            printNum(screenNum[i]);
            j=100; 
            while(j--) ;
            Led = 0x0;      //remove the double image
            LED_PLACE+=1;   //control the place
        }
    }
}
實驗接線

參考資料:

http://www.51hei.com/bbs/dpj-19896-1.html ——單片機論壇
http://blog.csdn.net/fanyuqa/article/details/48036529 ——CSDN fanyuqa博客

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,578評論 6 544
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,701評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,691評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,974評論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,694評論 6 413
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 56,026評論 1 329
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,015評論 3 450
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,193評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,719評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,442評論 3 360
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,668評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,151評論 5 365
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,846評論 3 351
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,255評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,592評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,394評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,635評論 2 380

推薦閱讀更多精彩內容

  • 前言 拋開工作,以電子愛好者的身份,單片機玩多了都會想著在單片機的外圍設備玩出一些花樣來。這其中首先想到的就是“升...
    淡定的H羊閱讀 67,274評論 16 58
  • Arduino Due有14個數字I/O,6個模擬I/O,一個復位開關,一個ICSP下載口,7-12v電源供電。 ...
    麥牛2013閱讀 3,359評論 0 8
  • 1、嵌入式系統的定義 (1)定義:以應用為中心,以計算機技術為基礎,軟硬件可裁剪,適應應用系統對功能、可靠性、成本...
    榮卓然閱讀 1,851評論 0 5
  • 什么是嵌入式 IEEE(Institute of Electrical and Electronics Engin...
    Leon_Geo閱讀 3,757評論 1 20
  • 一直盼著會下雨、淅淅瀝瀝、點點擊落、本來、應當是很有情懷的、可想到雨漬花落、紅散香凋、就有幾份凄迷、更有幾份感傷了...
    陳琳琳閱讀 174評論 0 0