C51 source program for keystrokes

Publisher:InspiredDreamerLatest update time:2016-03-25 Source: eefocusKeywords:Button Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere
C51 source code with 8 ports and 24 buttonsJuliet commented on 2006-5-10 11:35:00

96-key zero-delay acquisition
 
 
HotPower Published on 2003-11-5 18:04 Talking about microcontrollers ← Back to the page   

;-------96-key demonstration program-------------------------
;This is an application example in a reply question, which has been "verified" by software simulation
; This is just a "miniature" of key scanning technology, and there are too many methods.
;There are "ugly places", and experts are welcome to criticize and advise.
;HotPower will accept it humbly, resolutely correct it and make a new start.
;Purpose of publication: To strengthen the guerrillas in 21IC.
;----------------------------------------------------
;Due to the problem of 2051 resources, this program only takes the two events of the press and release keys of the multi-tasking keyboard
; Abolish the long press key event (press the key for a period of time before activation)
; Abolish the long release key event (release the key for a period of time before activation)
; Abolish the double-click key event
; Abolish any combination of key events
;----------Constant definition------------------------------
TIME208US  EQU -208;20mS/96=208uS
TIME50MS   EQU -5000;50000uS
;KEYCOUNT   EQU   1; Number of keyboard keys (used in software simulation)
;------------------------------------------------
KEYCOUNT   EQU   96; Number of keyboard keys (actual application)


;----------RAM address definition----------------------------
;--------96-key key status flag bit array Bits[12*8 bits]--------
KEYBUFF1   DATA  08H;08H~13H (12 bytes 96 bits) correspond to 96 keys
;--------96-key key jump flag bit array Bits[12*8 bits]--------
KEYBUFF2   DATA  14H;14H~1FH (12 bytes 96 bits) correspond to 96 keys
;------------------------------------------------
KEYNUM     DATA  30H;
HotPower_55H      DATA   6EH
HotPower_AAH      DATA   6FH
;---------------------------------------
SP_MIN       DATA HotPower_AAH
;-------Main program starts----------------------
   ORG   0000H
START:
   LJMP  MAINSTART;Main program starts
   ORG   0003H
;-------Power-off protection interrupt INT0 service program--------
INT0_INTADDR:
   RETI
   ORG   000BH
;-------Timer T0 interrupt service program------------
;Work in 8-bit automatic loading mode, interrupt once every 208uS T0_INTADDR 
:
   LJMP  T0INTPROC;Timer T0 interrupt service programRETI
   ORG 0013H ;-------External interrupt INT1 service program------------ INT1_INTADDR: RETI
   ORG  001BH ;-------Timer T1 interrupt service program------------ T1_INTADDR: LJMP  T1INTPROC;Timer T1 interrupt service programRETI ; ORG  0023H ;-------Serial interrupt service program---------------- ;  SINT_INTADDR: ;  RETI ;------------------------------------------- ;  ORG  002BH ;-------Timer T2 interrupt service program------------ ;  LJMP  T2INTPROC;Execute interrupt service program ;  RETI ;-------Execute keyboard command---------------------- ;This program uses the scattered transfer recovery technology (pointer function) ; its biggest advantage is that the subroutine at the scattered transfer location can be used by it (function) ; it is much more "guerrilla" than the JMP @A+DPTR instruction, and is much more flexible and hidden ; it is "worse" than JMP @A+DPTR in dealing with "disassembly" ; HotPower would never use JMP @A+DPTR KEYPROC: ;Entrance:  DPTR scattered transfer address table ;  ACC scattered transfer number CJNE  A,#KEYCOUNT,$+3 JNC  KEYPROC_EXIT; illegal keys (96~255) prevent program flying, no scattered transfer RL  A; *2; address requires 2 bytes (like ARM big-endian mode) ADD  A,DPL MOV  DPL,A CLR  A ADDC  A,DPH MOV  DPH,A MOV  A,#01H; low 8 bits MOVC  A,@A+DPTR; take the low 8 bits address PUSH  ACC; push the low 8 bits address CLR  of event processing A; MOVC  A, @A+DPTR; Get the high 8-bit address PUSH  ACC; Push the high 8-bit address of the event processing KEYPROC_EXIT: RET; Execute the keyboard command (JMP @A+DPTR) 


   
    


   
   
   


  

   

  
  








     
   
    
     
    
    
    
   
    
    
   
       
        
   
       

   
;-------Key press event processing address table--------------------
KEYJMPPROCTAB:
   DW    KEYPROC0;0 key press
   DW    KEYPROC1
   DW    KEYPROC2
;............................
   DW    KEYPROC95;95 key press
;-------Key release event processing address table--------------------
KEYJMPPROCTABX:
   DW    KEYPROC0X;0 key release
   DW    KEYPROC1X
   DW    KEYPROC2X
;............................
   DW    KEYPROC95X;95 key release
MAINSTART:
;----------P0 port initialization------------------
   MOV   P0,#11111111B
;-------P1 port initialization------------------
   MOV   P1,#11111111B
;-------P2 port initialization------------------
   MOV   P2,#11111111B
;-------P3 port initialization------------------
   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;System initialization
       MOV   IE,#10001010B;Open interrupt
;-------Main loop-------------------------------
MAINLOOP:
   ORL   PCON,#10001101B;Standby
   SJMP  MAINLOOP;Dead loop
MAINNEXT:
   MOV   A,#LOW(MAINPROC)
   PUSH  ACC
   MOV   A,#HIGH(MAINPROC)
   PUSH  ACC
   RETI
;-------Main program initialization------------------------
MAININIT:
;-------Interface initialization--------------------------
;-------Memory initialization-------------------------
   MOV   A,HotPower_55H
   XRL   A,HotPower_AAH
   CPL   A
   JZ    MAININITNEXT;Memory is not destroyed
   MOV   HotPower_55H,#055H
   MOV   HotPower_AAH,#0AAH
   LCALL SYSTEMINIT;System initialization
MAININITNEXT:
;-------Run initialization---------------
   LCALL SYSTEMSETUP;System setup
   RET
SYSTEMINIT:
   LCALL KEYBUFFINIT
   RET
SYSTEMSETUP:
;-------System main frequency 12MHz---------------------------------
  MOV   IP,#00100001B;Interrupt priority EX0>ET2>ET0>EX1>ES
    MOV   TMOD,#00010010B;T1=MODE1(16-bit timer),T0=MODE2(8-bit timer)
   MOV   TCON,#01010101B;Start timer TR1EQUTR0EQU1,IT1EQUIT0EQU1
;------------------------------------------------------
   MOV   TL0,#TIME208US;Set timer 0 time constant
   MOV   TH0,#TIME208US;Set timer 0 time constant
;------------------------------------------------------
  MOV   TL1,#LOW(TIMEXMS);Set timer 1 time constant
  MOV   TH1,#HIGH(TIMEXMS)
;-------
KEYBUFFINIT:
   MOV   KEYNUM,#00H
   MOV   R0,#KEYBUFF1
KEYBUFFINITLOOP:
   MOV   @R0,#00H
   INC   R0
   CJNE  R0,#KEYBUFF2+12,KEYBUFFINITLOOP
   RET
;---------------------------------------------
INKEY:
;Every time T0 is interrupted, a key "scan" will be performed
   LCALL TESTKEY;Keyboard test (no scanning but description)
;-------Keyboard soft simulation test point-----------------
;Here   A=0 No key is pressed, A<>0 has a key pressed
; if debugging n keys, KEYCOUNT needs to be set to n. (KEYCOUNT=1~96)
;----------------------------------------
   JNZ   INKEY1; A key is pressed
INKEY0:
;-------No key is pressed------------------------
   LCALL GETKEYBIT; Get key status
   JZ    INKEY01; The key status has not changed
       LCALL CLRKEYBIT; Set the key release flag
   LCALL SETKEYBITK; Set the jump flag (to prevent key release jitter)
   RET
INKEY01:
   LCALL GETKEYBITK; Get the key jump flag
   JZ    INKEY02; The key has not jumped (to prevent double event processing)
   LCALL CLRKEYBITX; Set the reentry flag
       MOV   A,KEYNUM; Get the key number
       MOV   DPTR,#KEYJMPPROCTABX; Keyboard key release event processing table
   LCALL KEYPROC; Execute keyboard key release event processing
INKEY02:
   RET
INKEY1:
;-------A key is pressed------------------------
   LCALL GETKEYBIT;Get key status
   JNZ   INKEY11;The key status has not changed (to prevent double event processing)
       LCALL SETKEYBIT;Set key pressed flag
   LCALL SETKEYBITK;Set transition flag (to prevent key pressed jitter)
   RET
INKEY11:
   LCALL GETKEYBITK;Get key transition flag
   JZ    INKEY12;The key has not transitioned
   LCALL CLRKEYBITX;Set reentry flag
       MOV   A,KEYNUM;Get key number
       MOV   DPTR,#KEYJMPPROCTAB;Keyboard key pressed event processing table
   LCALL KEYPROC;Execute keyboard key pressed event processing
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; Negate B
       ANL   A,B
   XRL   B,#0FFH; restore 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+PC
GETKEYBITTABOFF:
   MOV   B,A
   RET GETKEYBITTAB
:
   DB    00000001B
   DB    00000010B
   DB    00000100B
   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 ;-------Key test subroutine----------------- --------- TESTKEY: ;Key number KEYNUM=000 0000B~101 1111B(0~95) ;Entry  None ;Exit  ACC==0 No key pressed (key number KEYNUM) ;  ACC<>0 A key is pressed (key number KEYNUM) MOV  A,KEYNUM; get key number ANL  A,#0FH; get line number (lower 4 bits of key number) ANL  P3,#0F0H; clear line signal ORL  P3,A; send line scan signal DCBA; P3.3~P3.0 MOV  A,KEYNUM; get the key number ANL  A,#01110000B; get the column number (the upper 3 bits of the key number) SWAP  A; change to the lower 3 bits ADD 
     
   


    
    
     
     
     
    
    
   



 
 
     
    
    
    
    
    
    
   
    A,#TESTKEYTAB-TESTKEYTABOFF; get the table address
       MOVC  A,@A+PC; get the table value
TESTKEYTABOFF:
   JZ    TESTKEYEXIT; 6,7 illegal columns, it is considered that no key is pressed
   PUSH  B; protect the scene
   MOV   B,A; temporarily store
   ANL   A,P1; receive column values ​​P1.7~P1.2, if a key is pressed, it is 0
   XRL   A,B; if a key is pressed, it is not 0
   POP   B; restore the scene
TESTKEYEXIT:
   RET
TESTKEYTAB:
   DB    00000100B; 0 column
   DB    000010000B; 1 column
   DB    00010000B; 2 column
   DB    00100000B; 3 column
   DB    01000000B; 4 column
   DB    10000000B; 5 column
   DB    00000000B; 6 column illegal
   DB    00000000B;7 columns are illegal
;-------Timer T0 interrupt service program--------------------
;Each key is scanned once every 20ms, and the key pressing or releasing is automatically debounced
;This is an atypical example of a large-scale (96-key) keyboard guerrilla war
;Features:
;1. No key scanning is required. (The order of T0 interrupt is the key scan number)
;2. No key debounce is required. (The key is automatically debounced after 96 T0 interrupts)
;3. Separation of key pressing and releasing events (scattered transfer recovery technology)
;4. "Parallel processing" of user events (mS level time sharing)
T0INTPROC:
   PUSH  PSW
   PUSH  ACC
   PUSH  B
   PUSH  DPL
   PUSH  DPH
T0INTPROC_START:
   LCALL INKEY;Key scan and execute key pressing and releasing event processing
   INC   KEYNUM;Prepare for the next key number (T0 interrupt count)
   MOV   A,KEYNUM
   CJNE  A,#KEYCOUNT,T0INTPROC_EXIT
   MOV   KEYNUM,#00H; Start the next round of key scan
T0INTPROC_EXIT:
   POP   DPH
   POP   DPL
   POP   B
   POP   ACC
   POP   PSW
   RETI
;------Timer T1 interrupt service program------------
T1INTPROC:
   RETI
;-------0 key press event processing---------------------
KEYPROC0:
;Add user key press event
   hereRET
;-------1 key press event processing---------------------
KEYPROC1:
;Add user key press event
   hereRET
;-------2 key press event processing---------------------
KEYPROC2:
;Add user key press event
   hereRET
;-------95 key press event processing---------------------
KEYPROC95:
;Add user key press event
   hereRET
;-------0 key release event processing---------------------
KEYPROC0X:
;Add user key release event hereRET
   ;
-------1 key release event processing---------------------
KEYPROC1X:
;Add user key release event here
   RET
;-------2 key release event processing---------------------
KEYPROC2X:
;Add user key release event here
   RET
;-------95 key release event processing---------------------
KEYPROC95X:
;Add user key release event here
   RET
;-------All programs end--------------------------------------
   END

 


 Key Scan DriverJuliet commented on 2006-5-10 11:35:00

Key scan driver
 
 
//Key scan driver

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

//Buttons connected to 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)) {  //Release the key. If the previous key press time is less than 1 second, read the key value
  key=kpush;
 }
 if ((++key_h)>200) key_h=200;
 key_l=0;
 if (key>=0x80) key=0;       //If the previous key press was long pressed for 1 second, clear the key value
 } else {
 kpush=P1&0x7;
 key_l++;
 if ((key_l>800)&&(key_h>30)) {     //If the key press exceeds 1 second, add 0x80 to the key value to mark the long press
  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;
 }
 }
}


Keywords:Button Reference address:C51 source program for keystrokes

Previous article:51 MCU IO port simulation serial communication C source code
Next article:At89c51 MCU keyboard scanning and display program

Latest Microcontroller Articles
  • Download from the Internet--ARM Getting Started Notes
    A brief introduction: From today on, the ARM notebook of the rookie is open, and it can be regarded as a place to store these notes. Why publish it? Maybe you are interested in it. In fact, the reason for these notes is ...
  • Learn ARM development(22)
    Turning off and on interrupts Interrupts are an efficient dialogue mechanism, but sometimes you don't want to interrupt the program while it is running. For example, when you are printing something, the program suddenly interrupts and another ...
  • Learn ARM development(21)
    First, declare the task pointer, because it will be used later. Task pointer volatile TASK_TCB* volatile g_pCurrentTask = NULL;volatile TASK_TCB* vol ...
  • Learn ARM development(20)
    With the previous Tick interrupt, the basic task switching conditions are ready. However, this "easterly" is also difficult to understand. Only through continuous practice can we understand it. ...
  • Learn ARM development(19)
    After many days of hard work, I finally got the interrupt working. But in order to allow RTOS to use timer interrupts, what kind of interrupts can be implemented in S3C44B0? There are two methods in S3C44B0. ...
  • Learn ARM development(14)
  • Learn ARM development(15)
  • Learn ARM development(16)
  • Learn ARM development(17)
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号