Hola QuijotescoXP se nota que te lo has currado. Tú librería me funciona perfectamente en Proteus (aunque habría que probarla en un circuito real), además está perfectamente explicada. Como te dije que contarás con mi ayuda, aquí tienes mi primera aportación a tú librería. He hecho una pequeña modificación en el código para que se pueda utilizar indistintamente en el Puerto B ó D. Aquí va el código.
- Código: Seleccionar todo
/*******************************************************************************
* Modificación Nº1 de la Librería_Teclado 4X4 hecha por QuijotescoXP * *
* LICENCIA : GPL * *
* DESCRIPCIÓN: Esta modificación permite conectar el tecaldo al puerto B ó al D*
* *
*******************************************************************************/
//Para usar el puerto B descomenta la siguiente línea
//#define uso_puertoB_teclado4x4 TRUE
#if defined uso_puertoB_teclado4x4
#byte puerto = 6
#bit ROW_3 = 0x06.7 // Identificadores de bits puerto B
#bit ROW_2 = 0x06.6
#bit ROW_1 = 0x06.5
#bit ROW_0 = 0x06.4
#else
#byte puerto = 8
#bit ROW_3 = 0x08.7 // Identificadores de bits puerto D
#bit ROW_2 = 0x08.6
#bit ROW_1 = 0x08.5
#bit ROW_0 = 0x08.4
#endif
/* DEFINICIÓN DE CONSTANTES SIMBÓLICAS ****************************************/
#define COLUMN_0 1
#define COLUMN_1 2
#define COLUMN_2 4
#define COLUMN_3 8
#define NUMBER_COLUMNS 4
#define NUMBER_ROWS 4
#define DEBOUNCER_DELAY 30
/* DEFINICIÓN DE CONSTANTES ************************************/
char const matrixKeyBoard[ NUMBER_ROWS ][ NUMBER_COLUMNS ] =
{
/* Disposición del teclado */
'1', '2', '3', 'F',
'4', '5', '6', 'E',
'7', '8', '9', 'D',
'A', '0', 'B', 'C',
};
/* DEFINICIÓN DE VARIABLES LOCALES *******************************/
static unsigned column;
/* FUNCIONES PÚBLICAS *******************************************/
void mkd_int( char x )
{
switch( x )
{
case 'B':
set_tris_b( 0xF0 ); /* <RB7:RB4> como entrada, <RB3:RB0> como salida */
break;
case 'D':
set_tris_d( 0xF0);/* <RD7:RD4> como entrada, <RD3:RD0> como salida */
break;
}
puerto = 0;
column = 0;
}
char mkd_keyPress( void )
{
static char keyPress = '\0';
/* Se ha de esperar aprox. 30 ms para evitar el rebote del teclado */
delay_ms( DEBOUNCER_DELAY );
/* Se comienza activando una columna */
switch( column )
{
case 0:
/* Se pone a 1 la columna 0 */
puerto = COLUMN_0;
break;
case 1:
/* Se pone a 1 la columna 1 */
puerto = COLUMN_1;
break;
case 2:
/* Se pone a 1 la columna 2 */
puerto = COLUMN_2;
break;
case 3:
/* Se pone a 1 la columna 3 */
puerto = COLUMN_3;
break;
}
/* Se rastrea si hay pulsación en la columna activa */
if( ROW_0 == 1 )
{
keyPress = matrixKeyBoard[ 0 ][ column ];
}
else if( ROW_1 == 1 )
{
keyPress = matrixKeyBoard[ 1 ][ column ];
}
else if( ROW_2 == 1 )
{
keyPress = matrixKeyBoard[ 2 ][ column ];
}
else if( ROW_3 == 1 )
{
keyPress = matrixKeyBoard[ 3 ][ column ];
}
if( 3 == column )
{
/* Se completo un ciclo, reiniciamos nuevamente */
column = 0;
}
else
{
column++;
}
return( keyPress );
}
Programa principal:
- Código: Seleccionar todo
/*--------------------------------------------------------*\
| Comunicación entre dos PIC's por USART. Transmisor |
| autor: biblioman |
| www.aquihayapuntes.com |
\*--------------------------------------------------------*/
#include <16F877.h>
#use delay (clock = 4000000)
#FUSES NOWDT, XT, NOPUT, NOPROTECT, NOBROWNOUT, NOLVP, NOCPD, NOWRT, NODEBUG
#use rs232(uart1, baud=9600)//usart1 -->ajuste de XMIT y RCV para la USART 1
#include "Libreria_Teclado4X4.c"
void main() {
char c;
//mkd_int('B'); //inizializo drivers teclado para puerto B
mkd_int ('D'); //inicializo drivers teclado para puerto D
while(true)
{
c = mkd_keyPress();
if(c != 0 )//si se ha pulsado una tecla
{
putc(c);//Envía el caracter vía serie por la USART del PIC
}
}
}
Algunos comentarios constructivos:
QuijotescoXp escribió:Sólo es válido para el puerto B, por lo tanto hay que tener en cuenta una posible inclusión de resistencias PULLUP.
Efectivamente si incluimos las PULLUP del puerto B, se tiene que tener en cuenta en la lógica del programa, como te habrás dado cuenta, no basta con poner la instrucción:
port_b_pullups(true);QuijotescoXp escribió:Se mete un retardo de 30 ms para evitar el problema del rebote en las pulsaciones del teclado. Este parámetro podríamos configurarlo en la llamada a la función de inicio.
Lo de meter el retardo como un parámetro, me parece bien. Pero el problema lo veo en el propio retardo, es decir, al no utilizar interrupciones , si no se pulsa ninguna tecla el programa no hará nada, pero estaremos desperdiciando 30 ms de tiempo de procesador en cada ciclo while, que no podremos emplear en hacer otras cosas. Habría que ver en que circuitos podría ser esto una limitación.
En conclusión, como te he dicho al principio se nota que te lo has currado, enhorabuena.
Un saludo y hasta la próxima.
El DNS para el puerto D lo tienes aquí
No tiene los permisos requeridos para ver los archivos adjuntos a este mensaje.