Saludos de nuevo Cryn
Sip, uso el desplazamiento de bits, mira un extracto de
teclado_flex_change_portb.c...
void Configurar_iPuerto_compuesto(void){
iPuerto_compuesto=0;
iPuerto_compuesto = input_b() & iLos_Cuatro_MSB_PORTB;
iPuerto_compuesto |= (input_state(iColumna3) << 3);
iPuerto_compuesto |= (input_state(iColumna2) << 2);
iPuerto_compuesto |= (input_state(iColumna1) << 1);
iPuerto_compuesto |= input_state(iColumna0);
}
...
El funcionamiento sigue así:
- interrupción timer0 = deshabilitada
- interrupción por cambio de flanco en RB[7-4] (int_rb) = habilitada
- bucle prinicipal activo
- al producirse una pulsación, ocurre un cambio de flanco en RB, por lo que ocurrirá una interrupción int_rb
- En la función
void control_rb(), configuro y activo el timer0 no sin antes haber guardado el dato que corresponde a la tecla pulsada.
- se deshabilita int_rb
- a partir de allí, seguirá el bucle principal activo, ocurriendo una interrupción timer0 cada milisegundo.
- En cada interrupción timer0, se incrementará un contador, cuando dicho contador llegue a 30, es porque han transcurrido ~30ms desde que se pulsó la tecla, entonces hago una nueva lectura de los pines asociados al teclado matricial.
- Si esa nueva lectura coincide con la lectura que tomé al inicio de int_rb, quiere decir que efectivamente es una pulsación válida y la tomo como tal para procesar futuros eventos.
- el resto es limpiar las variables asociadas al timer, deshabilitarlo y habilitar el int_rb para una futura pulsación.
notas:
- ten en cuenta que en el intervalo de los 30ms, si pulsas una tecla, no ocurrirá nada, porque int_rb es deshabilitada.
- se toman las previsiones respectivas de limpiar el puerto, etc. para permitir una int_rb a posteriori.
- La finalidad del timer0 es antirebotes unicamente (base de tiempo de 1ms).