機(jī)電之家資源網(wǎng)
單片機(jī)首頁|單片機(jī)基礎(chǔ)|單片機(jī)應(yīng)用|單片機(jī)開發(fā)|單片機(jī)文案|軟件資料下載|音響制作|電路圖下載 |嵌入式開發(fā)
培訓(xùn)信息
贊助商
單片機(jī)鍵盤輸入編程
單片機(jī)鍵盤輸入編程
 更新時間:2009-9-17 15:59:21  點(diǎn)擊數(shù):0
【字體: 字體顏色
學(xué)習(xí)過單片機(jī)技術(shù)的人都知道,單片機(jī)的按鍵輸入一般可分為簡單的獨(dú)立式按鍵輸入及行列式鍵盤輸入兩種。圖1為簡單的獨(dú)立式鍵盤輸入示意圖,獨(dú)立式鍵盤輸入適合于按鍵輸入不多的情況(<5個按鍵),具有占用口線較少、軟件編寫簡單容易等特點(diǎn)。
  

  圖2為行列式鍵盤輸入示意圖,列線接P1.0~P1.3,行線接P1.4~P1.7。行列式鍵盤輸入適合于按鍵輸入多的情況,如有16個按鍵輸入,用簡單按鍵輸入用要占用2個輸入口(共16位),而使用行列式鍵盤輸入只需占用一個輸入口(8位)。但行列式鍵盤輸入軟件編寫較復(fù)雜,對初學(xué)者而言有一定的難度。
  

  以上略談了一下按鍵輸入的情況。在很多狀態(tài)下,按鍵輸入的值要同時要在LED數(shù)碼管上顯示出來。如一個按鍵設(shè)計為輸入遞增(加法)鍵,可以設(shè)計成每點(diǎn)按一下,數(shù)值遞增加1,同時在LED數(shù)碼管上顯示出來;也可設(shè)計成持續(xù)按下時,數(shù)值以一定時間間隔(如0.3秒)累加。但是當(dāng)欲輸入值較大時(如三位LED數(shù)碼管作輸入顯示時的輸入值最大為999),則可能按下鍵的時間太長(最長達(dá)300秒),看來這種方式只適用于一位或至多兩位數(shù)值(最大99)的輸入。當(dāng)然你也可多設(shè)幾個鍵,每個鍵只負(fù)責(zé)一位數(shù)值的輸入,但這樣會占用較多的口線,浪費(fèi)寶貴的硬件資源。

  大家可能見到過,一些進(jìn)口的溫度控制器(如日本RKC INSTRUMENT INC. 生產(chǎn)的REX_C700溫控器)的面板設(shè)計為:溫度測量值用4位LED數(shù)碼管顯示,輸入設(shè)定值顯示也用4位LED數(shù)碼管,輸入按鍵只有4個,一個為“模式設(shè)定鍵”,一個為“左移鍵”,另兩個為“加法鍵”、“減法鍵”。欲輸入設(shè)定值(溫控值)時,按一下“模式設(shè)定鍵”,程序進(jìn)入設(shè)定狀態(tài),此時輸入設(shè)定值顯示的4位LED數(shù)碼管中,個位顯示最亮(穩(wěn)定顯示),而十、百、千位顯示較暗(有閃爍感),說明可對個位進(jìn)行輸入。按下“加法鍵”或“減法鍵”,即可輸入個位數(shù)的值;點(diǎn)按一下“左移鍵”,變?yōu)槭伙@示最亮,而個、百、千位顯示較暗,說明可對十位進(jìn)行輸入。按下“加法鍵”或“減法鍵”,即可輸入十位數(shù)的值;……這樣可完成4位數(shù)的輸入。完成輸入后,再按一下“模式設(shè)定鍵”,程序即退出設(shè)定狀態(tài),進(jìn)入工作運(yùn)行。用這種輸入方法,不僅輸入4位數(shù)用4個鍵即可,再多位(5位至24位)的輸入也用這4個鍵就夠了。

    大家了解了這種新穎的按鍵輸入方式后,一定很感興趣,也想掌握設(shè)計方法。為了便于大家理解,這里結(jié)合筆者設(shè)計的一款“節(jié)能時控器”,詳細(xì)進(jìn)行講解!肮(jié)能時控器”用于定時控制大功率電器工作,因現(xiàn)采用分時計費(fèi)方法,可起到節(jié)約開支的作用,對工業(yè)生產(chǎn)成效顯著。

    圖3為“節(jié)能時控器”硬件構(gòu)成原理圖。“節(jié)能時控器”共有4個輸入按鍵:set--模式設(shè)定鍵,left--左移鍵,up—加法鍵,on/off--定時1、2啟動/關(guān)閉鍵。單片機(jī)IC1(AT89C2051)只有15條I/O線,由于受I/O線數(shù)量限制,因此P1口中的P1.0~P1.3既作為驅(qū)動4位LED數(shù)碼管的數(shù)據(jù)輸出一部分,同時也用作按鍵的輸入。無疑,這種方式大大節(jié)約了硬件的I/O線,但也給編程者提出了更高的技術(shù)要求。限于篇幅,我們只對要詳解的按鍵輸入程序進(jìn)行分析,其它部分只略作介紹。如讀者需“節(jié)能時控器”詳細(xì)的源程序,可以Email:xuyuandz@163.com與作者聯(lián)系。
 

  圖4為主程序狀態(tài)流程圖?梢娭鞒绦蛑回(fù)責(zé)進(jìn)行走時或調(diào)整時間的運(yùn)算及顯示,而判斷按鍵輸入則放在T1定時中斷(10mS)服務(wù)子程序中。T0作為走時的基準(zhǔn)被設(shè)置為100mS定時中斷。這種設(shè)計的優(yōu)點(diǎn)是大大簡化了主程序設(shè)計,并且CPU會定時關(guān)心鍵盤,只要定時中斷時間足夠短(如為幾十mS),就不會漏掉每一次的按鍵輸入。
  

下面為判斷按鍵輸入的T1定時中斷服務(wù)子程序,序號為解釋方便而加。

/*10mS定時中斷服務(wù)子函數(shù)*/

序號   1:void zd1(void) interrupt 3

          2:{

          3:uchar i,j;i=P1;j=P3;

          4:TH1=-(5000/256);

          5:TL1=-(5000%256);

          6:if(m==1)n++;

          7:if(n>=30){n=0;m=0;}

          8:P3_7=0;

          9:P1=0xff;

          10:if(P1!=0xff)

          11:{

          12:if(n==0)m=1;

          13:{if(n==1)

          14:{

          15:if(P1_0==0){set++;left=0;}

          16:if(set>=4)set=0;

          17:if(set==1)flag=0x55;

          18:if(P1_1==0)left++;

          19:if(left>=4)left=0;

          20:if(P1_2==0){up++;

          21:switch(left)

         22:{ 

          23:case 0:{if(up>=10)up=0;}break;

          24:case 1:{if(up>=6)up=0;}break;

          25:case 2:{if(up>=10)up=0;}break;

          26:case 3:{if(up>=3)up=0;}break;

          27:default:break;

          28:}

          29:}

          30:if(P1_2==0){

          31:switch(set)

          32:{case 0:break;

          33:case 1:x[left]=up;break;

          34:case 2:{y[left]=up;if(P1_3==0)o_f1=!o_f1;}break;

          35:case 3:{z[left]=up;if(P1_3==0)o_f2=!o_f2;}break;

          36:default:break;

          37:}  }

          38:else {

          39:switch(set)

          40:{case 0:break;

          41:case 1:up=x[left];break;

          42:case 2:{up=y[left];if(P1_3==0)o_f1=!o_f1;}break;

          43:case 3:{up=z[left];if(P1_3==0)o_f2=!o_f2;}break;

          44:default:break;}

45     :}}

          46:}}

          47:P1=i;P3=j;

          48:}

    序號1(程序解釋,以下同):聲明定時1中斷函數(shù)。

    序號2:定時1中斷函數(shù)開始。

    序號3:定義i、j為無符號字符型局部變量。將當(dāng)時的P1口、P3口狀態(tài)送i、j暫存。

    序號4、5:定時器T1重新載入10mS初值。

    序號6:如變量m等于1,則變量n遞增。說明:m、n為整個程序開始時定義的無符號字符型全局變量。

    序號7:如變量n大于等于30,則m、n清零。

    序號8:P3.7置0,準(zhǔn)備讀取按鍵輸入。

    序號9:P1口置全1,準(zhǔn)備讀取按鍵輸入。

    序號10:如果P1口不等于全1,說明4個按鍵中有鍵按下。

    序號11:進(jìn)入if(P1!=0xff)語句范圍。

    序號12:如果n等于0,進(jìn)入if(n==0)語句,m置1。

    序號13:如果n等于1,進(jìn)入if(n==1)語句,同時進(jìn)行下面的具體判斷按鍵語句。作用效果為:開始時m、n均賦0,一旦有鍵按下,第一次中斷產(chǎn)生時m賦1;第二次中斷產(chǎn)生時n遞增。當(dāng)n等于1時(第二次中斷產(chǎn)生)進(jìn)入下面的具體判斷按鍵語句。若持續(xù)按下鍵,則第三次中斷產(chǎn)生~第三十一次中斷產(chǎn)生時,程序不進(jìn)入具體的判斷按鍵語句過程(因這時n不等于1)。由于中斷每10mS產(chǎn)生一次,這樣可實(shí)現(xiàn)每0.31秒(31x10=0.31秒)進(jìn)行一次加法或移位的操作,與人眼的視覺特性相吻合。

    序號14:進(jìn)入具體判斷按鍵語句范圍。

    序號15:如果P1.0等于0(即電路中的set鍵按下),變量set遞增,變量left清0。說明:set、left是為了判斷模式設(shè)定及左移而在整個程序開始時定義的無符號字符型全局變量。

    序號16:如果set大于等于4,則set清0。說明:set值只能在0~3間變化,只有4種工作模式(走時及輸出控制模式、走時調(diào)整模式、定時1調(diào)整模式、定時2調(diào)整模式)。

    序號17:在set等于1時,向RAM區(qū)標(biāo)志變量flag寫入55H。說明:flag是在整個程序開始時定義的無符號字符型全局變量,用作判斷RAM區(qū)是否受干擾的依據(jù)。

    序號18:如果P1.1等于0(即電路中的left鍵按下),變量left遞增。

    序號19:如果left大于等于4,則left清0。說明:left值只能在0~3間變化,LED數(shù)碼管只有4位顯示。

    序號20:如果P1.2等于0(即電路中的up鍵按下),進(jìn)入if(P1_2==0)語句,變量up遞增。說明:up是為了判斷數(shù)值增量而在整個程序開始時定義的無符號字符型全局變量。

    序號21:隨即進(jìn)入switch(left)開關(guān)語句。

    序號22:switch(left)開關(guān)語句開始。

    序號23:left值為0時,如果up大于等于10,則up清0。隨即退出。說明:電子鐘的個位可在0~9之間調(diào)整。

    序號24:left值為1時,如果up大于等于6,則up清0。隨即退出。說明:電子鐘的十位可在0~5之間調(diào)整。

    序號25:left值為2時,如果up大于等于10,則up清0。隨即退出。說明:電子鐘的百位可在0~9之間調(diào)整。

    序號26:left值為3時,如果up大于等于3,則up清0。隨即退出。說明:電子鐘的千位可在0~2之間調(diào)整。

    序號27:若left為其它值,也退出。

    序號28:switch(left)開關(guān)語句結(jié)束。

    序號29:if(P1_2==0)語句結(jié)束。

    序號30:如果P1.2等于0(即電路中的up鍵按下時),進(jìn)入if(P1_2==0)語句,同時進(jìn)入switch(set)開關(guān)語句。

    序號31:switch(set)開關(guān)語句開始。

    序號32:set值為0時,退出。

    序號33:set值為1時,將此時up值送入X數(shù)組的第left位。隨即退出。說明:X數(shù)組是顯示走時緩存區(qū)。

    序號34:set值為2時,將此時up值送入Y數(shù)組的第left位。若此時P1.3等于0(即電路中的on/off鍵按下),則定時1啟停標(biāo)志位o_f1取反(啟動/關(guān)閉)。隨即退出。說明:Y數(shù)組是定時1記憶緩存區(qū)。o_f1是為了判斷定時1啟動/關(guān)閉而在整個程序開始時定義的位標(biāo)志。

    序號35:set值為3時,將此時up值送入Z數(shù)組的第left位。若此時P1.3等于0(即電路中的on/off鍵按下),則定時2啟停標(biāo)志位o_f2取反(啟動/關(guān)閉)。隨即退出。說明:Z數(shù)組是定時2記憶緩存區(qū)。o_f2是為了判斷定時2啟動/關(guān)閉而在整個程序開始時定義的位標(biāo)志。

    序號36:若set為其它值,也退出。

    序號37:switch(set)開關(guān)語句結(jié)束。if(P1_2==0)語句結(jié)束。

    序號38:else語句開始。

    序號39:又進(jìn)入switch(set)開關(guān)語句。說明:上一個switch(set)開關(guān)語句是將按鍵產(chǎn)生的up值送入X、Y、Z數(shù)組存放,現(xiàn)在這個switch(set)開關(guān)語句是調(diào)出X、Y、Z數(shù)組內(nèi)容至變量up,以便在原來的基礎(chǔ)上遞增。例如:原來的X[0]值為5,則在調(diào)整時個位LED數(shù)碼管顯示就從5開始往上調(diào),而不會產(chǎn)生從0或其它值開始上調(diào)的情況,適合人的一般直覺。

    序號40:set值為0時,退出。

    序號41:set值為1時,將此時X數(shù)組的第left位值送入變量up。隨即退出。

    序號42:set值為2時,將此時Y數(shù)組的第left位值送入變量up。若此時P1.3等于0(即電路中的on/off鍵按下),則定時1啟停標(biāo)志位o_f1取反(啟動/關(guān)閉)。隨即退出。

    序號43:set值為3時,將此時Z數(shù)組的第left位值送入變量up。若此時P1.3等于0(即電路中的on/off鍵按下),則定時2啟停標(biāo)志位o_f2取反(啟動/關(guān)閉)。隨即退出。

    序號44:若set為其它值,也退出。

    序號45:switch(set)開關(guān)語句結(jié)束。else語句結(jié)束。

    序號46:if(n==0)語句結(jié)束。if(P1!=0xff)語句結(jié)束。

    序號47:本次定時中斷快結(jié)束時,將暫存于i,j的當(dāng)時P1口、P3口狀態(tài)還原。

    序號48:定時1中斷函數(shù)結(jié)束。

    上面為按鍵輸入程序設(shè)計的詳細(xì)解釋,按鍵輸入時需將當(dāng)時狀態(tài)實(shí)時顯示出來,我們將顯示走時、顯示調(diào)整走時、顯示調(diào)整定時1、顯示調(diào)整定時2做成四個子程序,分別由set為0、1、2、3時散轉(zhuǎn)后的“顯示走時并判斷定時1、2到否程序”、“顯示調(diào)整走時程序”、“顯示調(diào)整定時1程序”、“顯示調(diào)整定時2程序”進(jìn)行調(diào)用。為達(dá)到需輸入的某位顯示最亮(穩(wěn)定顯示),而其它三位顯示較暗(有閃爍感)的視覺效顯,讓三位需顯示較暗的數(shù)碼管每位點(diǎn)亮3mS,而顯示最亮的那位數(shù)碼管點(diǎn)亮36mS即可。限于篇幅,具體程序就不進(jìn)行詳解了,讀者朋友可自行編寫。

  • 上一篇: 在C51中變量的空間分配幾個方法
  • 下一篇: 沒有了
  • 發(fā)表評論   告訴好友   打印此文  收藏此頁  關(guān)閉窗口  返回頂部
    熱點(diǎn)文章
     
    推薦文章
     
    相關(guān)文章
    網(wǎng)友評論:(只顯示最新5條。)
    關(guān)于我們 | 聯(lián)系我們 | 廣告合作 | 付款方式 | 使用幫助 | 機(jī)電之家 | 會員助手 | 免費(fèi)鏈接

    點(diǎn)擊這里給我發(fā)消息66821730(技術(shù)支持)點(diǎn)擊這里給我發(fā)消息66821730(廣告投放) 點(diǎn)擊這里給我發(fā)消息41031197(編輯) 點(diǎn)擊這里給我發(fā)消息58733127(審核)
    本站提供的機(jī)電設(shè)備,機(jī)電供求等信息由機(jī)電企業(yè)自行提供,該企業(yè)負(fù)責(zé)信息內(nèi)容的真實(shí)性、準(zhǔn)確性和合法性。
    機(jī)電之家對此不承擔(dān)任何保證責(zé)任,有侵犯您利益的地方請聯(lián)系機(jī)電之家,機(jī)電之家將及時作出處理。
    Copyright 2007 機(jī)電之家 Inc All Rights Reserved.機(jī)電之家-由機(jī)電一體化網(wǎng)更名-聲明
    電話:0571-87774297 傳真:0571-87774298
    杭州濱興科技有限公司提供技術(shù)支持

    主辦:杭州市高新區(qū)(濱江)機(jī)電一體化學(xué)會
    中國行業(yè)電子商務(wù)100強(qiáng)網(wǎng)站

    網(wǎng)站經(jīng)營許可證:浙B2-20080178-1