;------------------------------ Key debounce example -------------------------- ;------------------------------ Hardware connections -------------------------- KEY_INPUT equ P1 ; key 0, 1 on port P1.0, P1.1 KEY0 equ 0 KEY1 equ 1 LED0 equ P2.0 LED1 equ P1.7 ;------------------------------ Data ------------------------------------------ dseg at 30h key_state: ds 1 key_press: ds 1 key_ct0: ds 1 key_ct1: ds 1 stack: ds 16 ;------------------------------ Code ------------------------------------------ cseg jmp init ;------------------------------ Interrupt vector table org 0000Bh ; Interrupt T0 jmp int_t0 ;------------------------------ Interrupt handler ----------------------------- ;Timebase 10ms at 12MHz: 12MHz / 12 / 100Hz = 10000 T0_reload equ 10000 ; int_t0: ; every 10ms (= 100Hz) push psw ; save registers push acc ;------------------------------ Reload for exact 10ms time base --------------- clr ea ; no additional delay by other interrupts clr tr0 ; no overflow during addition mov a, tl0 add a, #low(8-T0_reload) ; stop for 8 cycle mov tl0, a mov a, th0 addc a, #high(8-T0_reload) mov th0, a setb ea ; other interrupts enabled after next instr. setb tr0 ;------------------------------ Key debounce ---------------------------------- mov a, KEY_INPUT cpl a ; key inverted (low active) xrl a, key_state ; key changed ? anl key_ct0, a ; reset or count CT0 xrl key_ct0, #0FFh anl a, key_ct1 ; reset or count CT1 xrl a, key_ct0 mov key_ct1, a cpl a ; if roll over ? anl a, key_ct0 xrl key_state, a ; then toggle debounced state anl a, key_state orl key_press, a ; 0 -> 1: key press detect ;------------------------------ Insert other interrupt stuff ------------------ ; e.g. display multiplex ; e.g. count time ;------------------------------------------------------------------------------ pop acc pop psw reti ;------------------------------ Subroutines ----------------------------------- ;------------------------------ get key press --------------------------------- ;Input: A = key mask ;Output: A != 0: key pressed ; get_key_press: clr EA ; interrupt disable anl a, key_press xrl key_press, a setb EA ret ;------------------------------ Init stuff------------------------------------- init: mov SP, #stack-1 ; set stack after used data mov TMOD, #1 ; T0: Mode 1 (16 bit) setb TR0 ; run T0 setb ET0 ; enable T0 interrupt setb EA ;------------------------------ Main loop ------------------------------------- main: mov a, #1 shl KEY0 ; bit mask of key 0 call get_key_press jz _main1 CPL LED0 ; toggle LED 0 _main1: mov a, #1 shl KEY1 ; bit mask of key 1 call get_key_press jz main cpl LED1 ; toggle LED 1 jmp main ;------------------------------------------------------------------------------ end