Hola Peter2007, es cierto lo que te dicen los amigos Chaly29 y MigSantiago.
Lo puedes hacer por hardware con esos montajes de interruptores antirebotes que te coloca el amigo MigSantiago, o por software como comenta el amigo Chaly29.
Para este último punto te tengo dos sugerencias, puedes programar una rutina de retardo de 100ms o más, como comenta Chaly29, con la finalidad de que al pulsar una tecla, el micro se ponga a contar dando tiempo que el usuario deje de pulsar, o puedes hacer una rutina de espera cíclica, donde se pregunta el estado del pin de entrada, y hasta que el usuario no deje de pulsar la tecla, el micro no hace más nada que esa pregunta.
Te doy ejemplos de ambas situaciones en ASM:
1.- por retardo:
Al leer el pin del puerto correspondiente, llamas a la rutina de retardo, que no es más que 2 o 3 contadores que se decrementan hasta llegar a cero, para luego salir de la subrutina de retardo, dando tiempo suficiente a que el usurio haya dejado de pulsar.
Ejemplo de rutina de retardo al pulsar una tecla:
CLRF Cont1 ; Iniciar los registros a usar.
CLRF Cont2
MOVLW 0x05 ; Este valor lo adaptas a tus necesidades.
MOVWF Cont3
Contar DECFSZ Cont1,1 ; Decrementar en orden los contadores
GOTO Contar ; hasta que lleguen todos a cero y se
DECFSZ Cont2,1 ; retorna.
GOTO Contar
DECFSZ Cont3,1
RETURN
Para este caso, tienes que declarar previamente los contadores al inicio del programa, donde le debes asignar uno de los registro de propositos generales a cada uno, los cuales comienzan en la direccion 0D si no me equivoco (según recuerdo de memoria, no tengo el data sheet a la mano). Y en este caso yo les dí el nombre de Cont1, Cont2, etc, pero puedes darle el nombre que quieras, igual a la rutina que llamé Contar. Puedes cambiar en nombre, con tal que lo hagas repectivamente en cada parte del programa donde aparezca.
2.- Por rutina de espera cíclica, al detectar el pulso, se llama a la subrutina, pero el programa no sale de ella, sino hasta que el usuario deje de pulsar. Particularmente ésta es la que yo uso, por que evita que si algún objeto que se coloque, o caiga encima del taclado pulse alguna de las teclas por más tiempo del que esté programado en la rutina de retardo, y se sigan detectando falsas pulsaciones.
Ejemplo para leer cuatro pulsadores en el puerto B entre RB4 y RB7:
BTFSS PORTB,4 ;Primera columna = 0
GOTO antirebotes ;Sale si se ha pulsado tecla.
BTFSS PORTB,5 ;Segunda columna = 0
GOTO antirebotes ;Sale si se ha pulsado tecla.
BTFSS PORTB,6 ;Tercera columna = 0
GOTO antirebotes ;Sale si se ha pulsado tecla.
BTFSS PORTB,7 ;Cuarta columna = 0
GOTO antirebotes ;Sale si se ha pulsado tecla.
Espera1 BTFSS PORTB,4 ;Si no se suelta la tecla
GOTO Espera1 ;vuelve a esperar.
Espera2 BTFSS PORTB,5 ;Si no se suelta la tecla
GOTO Espera2 ;vuelve a esperar.
Espera3 BTFSS PORTB,6 ;Si no se suelta la tecla
GOTO Espera3 ;vuelve a esperar.
Espera4 BTFSS PORTB,7 ;Si no se suelta la tecla
GOTO Espera4 ;vuelve a esperar.
Despues puedes seguir con la continuidad de tu programa, o puedes sustituir los GOTO antirebote, por CALL antirebote, y finalizar la subrutina con un RETURN. Pero tendrías que intercalar entre el programa principal, llamados a las tareas que quieras realizar al pulsar cada tecla.
Espero que te sea util.
Saludos...