;Dekodierung 16 Tasten (digitast) mit LEDs ;22.10.89 ;abgemagerte Demoversion: keine timer-routinen, keine LEDs ;char getkey() liefert Taste oder 0x00 ;Initialisierung wird beim 1. Aufruf erledigt ;Tasten an PORT1 und PORT2 werden gegen Masse aktiviert ; ;2003-02-25 Michael Nowak, www.mino-elektronik.de name tastatur_leds public getkey ;int getkey(void) PORT1 equ P1 ;taster 1-8 PORT2 equ P2 ;taster 9-16 T0_TEILER equ 255-35 ;fuer ca. 100 Hz bei 11,059 MHz FIRST_REPEAT EQU 70 ;NACH 0,7 SEKUNDE NEXT_REPEAT EQU 10 ;0.1 SEKUNDEN ENTPRELLZEIT EQU 5 ;soviel Zeit muss sein ?pr?tastatur?tastatur_leds segment code bitbereich segment bit daten segment data rseg bitbereich ALT_DECODE: dbit 1; fuer alternative zeichen REP_FLAG: dbit 1 rseg daten ENTPRELLCTR: DS 1 ;MEHRFACH IST IMMER GUT INREG1: DS 2 ;GELESENE TASTER INREG2: DS 2 ;FUER ENTPRELLUNG INREG3: DS 2 ;EBENSO CHANGE: DS 2 ;AENDERUNGEN DER TASTER LAST_CHANGE: DS 2 ;MASKE FUER AUTO-REPEAT RETTEN REP_COUNTER: DS 1 ;ZEIT FUER REPEAT TASTER: DS 1 ;AKTUELLER WERT cseg at 0bh ;timer0 interrupt vector ljmp timer_int rseg ?pr?tastatur?tastatur_leds getkey: jb et0,getkey1 ;init des timers + lesen der Taste lcall init_t0 getkey1: clr a xch a,TASTER getkey2: mov r7,a ;in r7 bergeben ret init_t0: clr ea ;auf jeden Fall verbieten orl tmod,#1 mov th0, #T0_TEILER ;fuer ca. 100 Hz setb tr0 setb et0 ;enable setb ea ;ints zulassen ret timer_int: push psw push acc mov th0,#T0_TEILER ;register nachladen lcall get_taster pop acc pop psw reti TAST_IN: MOV A,PORT1 XRL A,#0FFh MOV INREG1,A MOV A,PORT2 XRL A,#0FFh MOV INREG1+1,A RET DECODE: PUSH 0 ;r0 wird gebraucht MOV A,INREG3 XRL A,INREG2 ANL A,INREG2 ;POSITIVE AENDERUNGEN FESTSTELLEN MOV CHANGE,A ;UND RETTEN MOV INREG3,INREG2 MOV A,INREG3+1 XRL A,INREG2+1 ANL A,INREG2+1 MOV CHANGE+1,A ;UND DIE OBEREN TASTER MOV INREG3+1,INREG2+1 ORL A,CHANGE ;UEBERHAUPT EINE AENDERUNG ? JNZ DECODE1 ;JA MOV A,REP_COUNTER ;EVENTUELL REPEAT ? JNB ACC.7,DECODE_END ;NOCH NICHT NEGATIV GEWORDEN JNB REP_FLAG,DECODE_END ;KEIN REPEAT MODUS MOV A,LAST_CHANGE ;LETZTEN WERT ANL A,INREG3 ;EVENTUELL WIEDERHOLEN MOV CHANGE,A ;WENN BIT NOCH GUELTIG IST MOV A,LAST_CHANGE+1 ANL A,INREG3+1 MOV CHANGE+1,A SETB ALT_DECODE ;ANDERE TABELLE NEHMEN MOV A,#NEXT_REPEAT ;WIEDERHOLZEIT AENDERN SJMP DECODE20 DECODE1: MOV LAST_CHANGE,CHANGE ;NORMALE AUSWERTUNG MOV LAST_CHANGE+1,CHANGE+1 ;RETTEN CLR ALT_DECODE ;NORMALE TABELLE VERWENDEN MOV A,#FIRST_REPEAT ;1. VERZOEGERUNGSZEIT DECODE20: MOV REP_COUNTER,A ;REPEAT VERZOEGERN ;TASTE SUCHEN MOV R0,#0 ;INDEX AUF TABELLE DECODE2: CLR C XCH A,CHANGE+1 RRC A XCH A,CHANGE+1 XCH A,CHANGE RRC A XCH A,CHANGE JC DECODE3 ;BIT IST GEFUNDEN INC R0 CJNE R0,#(DECTAB_REP-DECTAB),DECODE2 SJMP DECODE5 ;NICHT GEFUNDEN DECODE3: MOV A,CHANGE ORL A,CHANGE+1 ;NOCH MEHR BITS OBEN ? JNZ DECODE5 ;DAS DARF NICHT SEIN ! PUSH DPL PUSH DPH ;WIRD GEBRAUCHT JB ALT_DECODE,DECODE41 MOV DPTR,#DECTAB ;NORMALE TABELLE SJMP DECODE42 DECODE41: MOV DPTR,#DECTAB_REP ;REPEAT-TABELLE DECODE42: MOV A,R0 ;INDEX LADEN MOVC A,@A+DPTR POP DPH POP DPL JZ DECODE5 ;KEINE BRAUCHBARE TASTE MOV TASTER,A SETB REP_FLAG ;AUTO-REPEAT MOEGLICH SJMP DECODE_END DECODE5: CLR REP_FLAG ;KEIN REPEAT MOEGLICH DECODE_END: POP 0 RET DECTAB: DB 'ABCDEFGHIJKLMNOP' DECTAB_REP: DB 'abcdefghijklmnop' GET_TASTER: LCALL TAST_IN ;TASTER + SCHALTER LESEN dec REP_COUNTER MOV A,INREG1 CJNE A,INREG2,NEU_ENTPRELLEN MOV A,INREG1+1 CJNE A,INREG2+1,NEU_ENTPRELLEN INC ENTPRELLCTR MOV A,ENTPRELLCTR CLR C SUBB A,#ENTPRELLZEIT ;ZEIT VORBEI ? JC GET_TAST_END ;WARTEN LCALL DECODE NEU_ENTPRELLEN: MOV ENTPRELLCTR,#0 ;LOESCHEN MOV INREG2,INREG1 ;UND WERTE UMSCHAUFELN MOV INREG2+1,INREG1+1 GET_TAST_END: RET end