<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          按鍵的C51源程序

          作者: 時間:2016-11-22 來源:網(wǎng)絡(luò) 收藏
          8條口線24按鍵C51源程序

          //鍵盤掃描處理,無按鍵返回0,有按鍵返回鍵值,鍵值對應(yīng)于keycode[]下標(biāo)值。8條(以P2為例)口線24按鍵
          //鍵盤碼也可定義為局部數(shù)組變量
          unsigned char code keycode[]=
          {0x00,0xee,0xde,0xbe,0xed,0xdd,0xbd,0xeb,0xdb,0xbb,0xd7,0xe7,0xb7,0x7b,0x7d,0x7e,0x77,

          本文引用地址:http://www.ex-cimer.com/article/201611/319618.htm

          0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0x7f,0xbf};

          unsigned char keyread(void)
          { unsigned char i,j,x,k1,k2;
          P2=0xff;
          if(P2!=0xff)
          {k1=P2;
          delay();
          P2=0xff;
          if(P2!=0xff)
          {for(P2=0xff;P2!=0xff;P2=0xff)
          x=k1;}
          }
          else{x=0;
          }
          //以上判斷接地按鍵
          //以下判斷交叉按鍵(反轉(zhuǎn)法)
          if(x==0)
          {P2=0x0f;
          if(P2!=0x0f)
          {delay();
          P2=0x0f;
          if(P2!=0x0f)
          {k1=P2;
          P2=0xf0;
          if(P2!=0xf0)
          {k2=P2;
          for(P2=0xf0;P2!=0xf0;P2=0xf0)
          x=k1^k2;}
          }
          }
          else{x=0;} }
          if(x==0){i=0;}
          else{i=j=0xff;
          do{i++;j++;
          if(keycode[i]==x){j=24;}
          else if(j==24){i=0;}else{;} }

          while(j!=24);}

          return(i);
          }

          void delay()//延時
          { unsigned char b;
          for (b=0;b<=0xff;b++)
          {
          for (b=0;b<=0xff;b++)
          {;}
          }
          }



          96個key的零延時采集
          Juliet發(fā)表評論于2006-5-10 11:35:00

          96個key的零延時采集


          HotPower 發(fā)表于 2003-11-5 18:04 侃單片機(jī) ←返回版面

          ;-------96鍵演示程序-------------------------
          ;這是1個回復(fù)題中的應(yīng)用示例,已通過軟仿真“驗證”
          ;這只是鍵掃描技術(shù)的1個“縮影”,方法實在太多.
          ;有“難看之處”,敬請高手們批評指教.
          ;HotPower將虛心接受,堅決改正.重新做人.
          ;發(fā)表目的: 在21IC中壯大游擊隊.
          ;----------------------------------------------------
          ;由于2051資源問題,本程序只取多任務(wù)鍵盤的壓放鍵2個事件
          ;廢除長壓鍵(壓鍵1段時間后才激活)事件
          ;廢除長放鍵(放鍵1段時間后才激活)事件
          ;廢除雙擊鍵事件
          ;廢除任意組合鍵事件
          ;----------常數(shù)定義------------------------------
          TIME208US EQU -208;20mS/96=208uS
          TIME50MS EQU -5000;50000uS
          ;KEYCOUNT EQU 1;鍵盤鍵個數(shù)(軟仿真時用)
          ;------------------------------------------------
          KEYCOUNT EQU 96;鍵盤鍵個數(shù)(實際應(yīng)用)


          ;----------RAM地址定義----------------------------
          ;--------96鍵鍵狀態(tài)標(biāo)志位數(shù)組Bits[12*8位]--------
          KEYBUFF1 DATA 08H;08H~13H(12個字節(jié)96位)對應(yīng)96鍵
          ;--------96鍵鍵跳變標(biāo)志位數(shù)組Bits[12*8位]--------
          KEYBUFF2 DATA 14H;14H~1FH(12個字節(jié)96位)對應(yīng)96鍵
          ;------------------------------------------------
          KEYNUM DATA 30H;
          HotPower_55H DATA 6EH
          HotPower_AAH DATA 6FH
          ;---------------------------------------
          SP_MIN DATA HotPower_AAH
          ;-------主程序開始----------------------
          ORG 0000H
          START:
          LJMP MAINSTART;主程序開始
          ORG 0003H
          ;-------掉電保護(hù)中斷INT0服務(wù)程序--------
          INT0_INTADDR:
          RETI
          ORG 000BH
          ;-------定時器T0中斷服務(wù)程序------------
          ;工作在8位自動裝載方式,每208uS中斷一次
          T0_INTADDR:
          LJMP T0INTPROC;定時器T0中斷服務(wù)程序
          RETI
          ORG 0013H
          ;-------外部中斷INT1服務(wù)程序------------
          INT1_INTADDR:
          RETI
          ORG 001BH
          ;-------定時器T1中斷服務(wù)程序------------
          T1_INTADDR:
          LJMP T1INTPROC;定時器T1中斷服務(wù)程序
          RETI
          ; ORG 0023H
          ;-------串行中斷服務(wù)程序----------------
          ;SINT_INTADDR:
          ; RETI
          ;-------------------------------------------
          ; ORG 002BH
          ;-------定時器T2中斷服務(wù)程序------------
          ; LJMP T2INTPROC;執(zhí)行中斷服務(wù)程序
          ; RETI
          ;-------執(zhí)行鍵盤命令----------------------
          ;本程序利用散轉(zhuǎn)回收技術(shù)(指針函數(shù))
          ;它的最大優(yōu)點是散轉(zhuǎn)處的子程序可被它用(函數(shù))
          ;它比JMP @A+DPTR指令要“游擊”很多,靈活和隱蔽了許多
          ;它在對付“反匯編”方面,比JMP @A+DPTR更“壞”
          ;HotPower打死也不用JMP @A+DPTR
          KEYPROC:
          ;入口: DPTR散轉(zhuǎn)地址表
          ; ACC 散轉(zhuǎn)號
          CJNE A,#KEYCOUNT,$+3
          JNC KEYPROC_EXIT;非法鍵(96~255)防止程序飛,不散轉(zhuǎn)
          RL A;*2;地址需要2字節(jié)(像ARM的大端模式)
          ADD A,DPL
          MOV DPL,A
          CLR A
          ADDC A,DPH
          MOV DPH,A
          MOV A,#01H;低8位
          MOVC A,@A+DPTR;取低8位地址
          PUSH ACC;壓入事件處理低8位地址
          CLR A;高8位
          MOVC A,@A+DPTR;取高8位地址
          PUSH ACC;壓入事件處理高8位地址
          KEYPROC_EXIT:
          RET;執(zhí)行鍵盤命令(散轉(zhuǎn)JMP @A+DPTR)
          ;-------壓鍵事件處理地址表--------------------
          KEYJMPPROCTAB:
          DW KEYPROC0;0鍵壓鍵
          DW KEYPROC1
          DW KEYPROC2
          ;............................
          DW KEYPROC95;95鍵壓鍵
          ;-------放鍵事件處理地址表--------------------
          KEYJMPPROCTABX:
          DW KEYPROC0X;0鍵放鍵
          DW KEYPROC1X
          DW KEYPROC2X
          ;............................
          DW KEYPROC95X;95鍵放鍵
          MAINSTART:
          ;-------P0口初始化------------------
          MOV P0,#11111111B
          ;-------P1口初始化------------------
          MOV P1,#11111111B
          ;-------P2口初始化------------------
          MOV P2,#11111111B
          ;-------P3口初始化------------------
          MOV P3,#11111111B
          ;--------------------------------
          MOV IE,#00000000B;EA=0,ES=ET2=ET1=EX1=ET0=EX0=0
          MOV SP,#SP_MIN;
          MOV PSW,#00000000B;RS1RS0=00,R0~R7=00H~07H
          MOV A,#LOW(MAINNEXT)
          PUSH ACC
          MOV A,#HIGH(MAINNEXT)
          PUSH ACC
          RETI
          MAINPROC:
          LCALL MAININIT;系統(tǒng)初始化
          MOV IE,#10001010B;開中斷
          ;-------主循環(huán)-------------------------------
          MAINLOOP:
          ORL PCON,#10001101B;待機(jī)
          SJMP MAINLOOP;死循環(huán)
          MAINNEXT:
          MOV A,#LOW(MAINPROC)
          PUSH ACC
          MOV A,#HIGH(MAINPROC)
          PUSH ACC
          RETI
          ;-------主程序初始化------------------------
          MAININIT:
          ;-------接口初始化--------------------------
          ;-------內(nèi)存初始化-------------------------
          MOV A,HotPower_55H
          XRL A,HotPower_AAH
          CPL A
          JZ MAININITNEXT;內(nèi)存未破壞
          MOV HotPower_55H,#055H
          MOV HotPower_AAH,#0AAH
          LCALL SYSTEMINIT;系統(tǒng)初始化
          MAININITNEXT:
          ;-------運行初始化---------------
          LCALL SYSTEMSETUP;系統(tǒng)設(shè)置
          RET
          SYSTEMINIT:
          LCALL KEYBUFFINIT
          RET
          SYSTEMSETUP:
          ;-------系統(tǒng)主頻12MHz---------------------------------
          ; MOV IP,#00100001B;中斷優(yōu)先級EX0>ET2>ET0>EX1>ES
          MOV TMOD,#00010010B;T1=MODE1(16位定時器),T0=MODE2(8位定時器)
          MOV TCON,#01010101B;啟動定時器TR1EQUTR0EQU1,IT1EQUIT0EQU1
          ;------------------------------------------------------
          MOV TL0,#TIME208US;設(shè)置定時器0時間常數(shù)
          MOV TH0,#TIME208US;設(shè)置定時器0時間常數(shù)
          ;------------------------------------------------------
          ; MOV TL1,#LOW(TIMEXMS);設(shè)置定時器1時間常數(shù)
          ; MOV TH1,#HIGH(TIMEXMS)
          ;-------
          KEYBUFFINIT:
          MOV KEYNUM,#00H
          MOV R0,#KEYBUFF1
          KEYBUFFINITLOOP:
          MOV @R0,#00H
          INC R0
          CJNE R0,#KEYBUFF2+12,KEYBUFFINITLOOP
          RET
          ;---------------------------------------------
          INKEY:
          ;T0每中斷1次,將進(jìn)行1次鍵"掃描"
          LCALL TESTKEY;鍵盤測試(不掃但描)
          ;-------鍵盤軟仿真測試點-----------------
          ;在此 A=0 無鍵壓下,A<>0有鍵壓下
          ;若調(diào)試n個鍵,需將KEYCOUNT設(shè)置為n.(KEYCOUNT=1~96)
          ;----------------------------------------
          JNZ INKEY1;有鍵壓下
          INKEY0:
          ;-------無鍵壓下------------------------
          LCALL GETKEYBIT;取鍵狀態(tài)
          JZ INKEY01;鍵狀態(tài)未發(fā)生變化
          LCALL CLRKEYBIT;設(shè)置放鍵標(biāo)志
          LCALL SETKEYBITK;設(shè)置跳變標(biāo)志(防止放鍵抖動)
          RET
          INKEY01:
          LCALL GETKEYBITK;取鍵跳變標(biāo)志
          JZ INKEY02;鍵未發(fā)生跳變(防止2次事件處理)
          LCALL CLRKEYBITX;設(shè)置重入標(biāo)志
          MOV A,KEYNUM;取鍵號
          MOV DPTR,#KEYJMPPROCTABX;鍵盤放鍵事件處理表
          LCALL KEYPROC;執(zhí)行鍵盤放鍵事件處理
          INKEY02:
          RET
          INKEY1:
          ;-------有鍵壓下------------------------
          LCALL GETKEYBIT;取鍵狀態(tài)
          JNZ INKEY11;鍵狀態(tài)未發(fā)生變化(防止2次事件處理)
          LCALL SETKEYBIT;設(shè)置壓鍵標(biāo)志
          LCALL SETKEYBITK;設(shè)置跳變標(biāo)志(防止壓鍵抖動)
          RET
          INKEY11:
          LCALL GETKEYBITK;取鍵跳變標(biāo)志
          JZ INKEY12;鍵未發(fā)生跳變
          LCALL CLRKEYBITX;設(shè)置重入標(biāo)志
          MOV A,KEYNUM;取鍵號
          MOV DPTR,#KEYJMPPROCTAB;鍵盤壓鍵事件處理表
          LCALL KEYPROC;執(zhí)行鍵盤壓鍵事件處理
          INKEY12:
          RET
          GETKEYBITK:
          MOV A,R0
          ADD A,#12
          MOV R0,A
          SJMP GETKEYBITX
          GETKEYBIT:
          LCALL GETKEYBITADDR
          LCALL GETKEYBITVAL
          GETKEYBITX:
          MOV A,@R0
          ANL A,B
          RET
          SETKEYBITK:
          MOV A,R0
          ADD A,#12
          MOV R0,A
          SJMP SETKEYBITX
          SETKEYBIT:
          LCALL GETKEYBITADDR
          LCALL GETKEYBITVAL
          SETKEYBITX:
          MOV A,@R0
          ORL A,B
          MOV @R0,A
          RET
          CLRKEYBITK:
          MOV A,R0
          ADD A,#12
          MOV R0,A
          SJMP CLRKEYBITX
          CLRKEYBIT:
          LCALL GETKEYBITADDR
          LCALL GETKEYBITVAL
          CLRKEYBITX:
          MOV A,@R0
          XRL B,#0FFH;取反B
          ANL A,B
          XRL B,#0FFH;還原B
          MOV @R0,A
          RET
          ;-----------------------------------
          ;CPLKEYBITK:
          ; MOV A,R0
          ; ADD A,#12
          ; MOV R0,A
          ; SJMP CPLKEYBITX
          ;CPLKEYBIT:
          ; LCALL GETKEYBITADDR
          ; LCALL GETKEYBITVAL
          ;CPLKEYBITX:
          ; MOV A,@R0
          ; XRL A,B
          ; MOV @R0,A
          ; RET
          ;---------------------------------------------
          GETKEYBITVAL:
          MOV A,KEYNUM
          ANL A,#07H
          ADD A,#GETKEYBITTAB-GETKEYBITTABOFF
          MOVC A,@A+PC
          GETKEYBITTABOFF:
          MOV B,A
          RET
          GETKEYBITTAB:
          DB 00000001B
          DB 00000010B
          DB 00000100B
          DB 00001000B
          DB 00010000B
          DB 00100000B
          DB 01000000B
          DB 10000000B
          RET
          ;----------------------------------------------
          GETKEYBITADDR:
          MOV A,KEYNUM
          ANL A,#01111000B
          RR A
          RR A
          RR A
          ADD A,#KEYBUFF1
          MOV R0,A
          RET
          ;-------鍵測試子程序--------------------------
          TESTKEY:
          ;鍵號KEYNUM=000 0000B~101 1111B(0~95)
          ;入口
          ;出口 ACC==0 無鍵壓下(鍵號KEYNUM)
          ; ACC<>0 有鍵壓下(鍵號KEYNUM)
          MOV A,KEYNUM;取鍵號
          ANL A,#0FH;取行號(鍵號低4位)
          ANL P3,#0F0H;清行信號
          ORL P3,A;發(fā)送行掃描信號DCBA;P3.3~P3.0
          MOV A,KEYNUM;取鍵號
          ANL A,#01110000B;取列號(鍵號高3位)
          SWAP A;變換到低3位
          ADD A,#TESTKEYTAB-TESTKEYTABOFF;得到表地址
          MOVC A,@A+PC;取列表值
          TESTKEYTABOFF:
          JZ TESTKEYEXIT;6,7非法列,認(rèn)為無鍵壓下
          PUSH B;保護(hù)現(xiàn)場
          MOV B,A;暫存
          ANL A,P1;接收列值P1.7~P1.2,有鍵壓下為0
          XRL A,B;有鍵壓下非0
          POP B;恢復(fù)現(xiàn)場
          TESTKEYEXIT:
          RET
          TESTKEYTAB:
          DB 00000100B;0列
          DB 00001000B;1列
          DB 00010000B;2列
          DB 00100000B;3列
          DB 01000000B;4列
          DB 10000000B;5列
          DB 00000000B;6列非法
          DB 00000000B;7列非法
          ;-------定時器T0中斷服務(wù)程序--------------------
          ;每個鍵20mS掃描1次,并自動進(jìn)行壓鍵或放鍵消抖處理
          ;這是1個大規(guī)模(96鍵)的鍵盤游擊戰(zhàn)的非典戰(zhàn)例
          ;特點:
          ;1.不需鍵掃描.(T0中斷的次序即為鍵掃描號)
          ;2.不需鍵消抖.(在T0中斷96次后自動消抖)
          ;3.壓鍵放鍵事件分離(散轉(zhuǎn)回收技術(shù))
          ;4.用戶事件"并行處理"(mS級分時)
          T0INTPROC:
          PUSH PSW
          PUSH ACC
          PUSH B
          PUSH DPL
          PUSH DPH
          T0INTPROC_START:
          LCALL INKEY;鍵掃描并執(zhí)行壓放鍵事件處理
          INC KEYNUM;準(zhǔn)備下一鍵號(T0中斷計數(shù))
          MOV A,KEYNUM
          CJNE A,#KEYCOUNT,T0INTPROC_EXIT
          MOV KEYNUM,#00H;開始下1輪鍵掃描
          T0INTPROC_EXIT:
          POP DPH
          POP DPL
          POP B
          POP ACC
          POP PSW
          RETI
          ;-------定時器T1中斷服務(wù)程序------------
          T1INTPROC:
          RETI
          ;-------0鍵壓鍵事件處理---------------------
          KEYPROC0:
          ;在此添加用戶壓鍵事件
          RET
          ;-------1鍵壓鍵事件處理---------------------
          KEYPROC1:
          ;在此添加用戶壓鍵事件
          RET
          ;-------2鍵壓鍵事件處理---------------------
          KEYPROC2:
          ;在此添加用戶壓鍵事件
          RET
          ;-------95鍵壓鍵事件處理---------------------
          KEYPROC95:
          ;在此添加用戶壓鍵事件
          RET
          ;-------0鍵放鍵事件處理---------------------
          KEYPROC0X:
          ;在此添加用戶放鍵事件
          RET
          ;-------1鍵放鍵事件處理---------------------
          KEYPROC1X:
          ;在此添加用戶放鍵事件
          RET
          ;-------2鍵放鍵事件處理---------------------
          KEYPROC2X:
          ;在此添加用戶放鍵事件
          RET
          ;-------95鍵放鍵事件處理---------------------
          KEYPROC95X:
          ;在此添加用戶放鍵事件
          RET
          ;-------全部程序結(jié)束--------------------------------------
          END



          按鍵掃描驅(qū)動程序
          Juliet發(fā)表評論于2006-5-10 11:35:00

          按鍵掃描驅(qū)動程序


          //按鍵掃描驅(qū)動程序

          unsigned char key,key_h,kpush;
          unsigned int key_l;

          //按鍵連接到p1.0、p1.1、p1.2

          void int_t0(void) interrupt 1 {
          unsigned char dd,i;
          TL0=TL0+30;TH0=0xfb; //800

          if ((P1&0x7)==0x7) {
          if ((key_l>30)&&(key_l<800)&&(key_h>30)) { //釋放按鍵,如果之前按鍵時間少于1秒,讀入鍵值
          key=kpush;
          }
          if ((++key_h)>200) key_h=200;
          key_l=0;
          if (key>=0x80) key=0; //如果之前的按鍵為長按1秒,清除鍵值
          } else {
          kpush=P1&0x7;
          key_l++;
          if ((key_l>800)&&(key_h>30)) { //如果按鍵超過1秒,鍵值加0x80標(biāo)志長按鍵
          key=kpush|0x80;
          key_h=0;
          key_l=0;
          }
          }
          }
          void main(void) {
          TMOD=0x1;TR0=1;ET0=1;EA=1;
          while (1) {
          while (!key) {}
          switch (key) {
          case 1:break;
          case 2:break;
          }
          }
          }




          關(guān)鍵詞: 按鍵C51源程

          評論


          技術(shù)專區(qū)

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();