Teclado programado en ccs

Buenas tardes gente...

Les paso a comentar rápido y claro, en CCS utilizaba la librería kbd.c para estos asuntos, me surge el siguiente problema: tengo que adaptarla a un teclado ya puesto, consta de:

-Las filas van a RA2,RA3,RA4,RA5
-Las columnas RE0,RE1,RE2 y estas tienen 3 Pull-down puestos (osea una de 10k a GND por pin).

Preguntaran porque tan jodido? Tenia otro tipo de lógica para detectar la pulsación de las teclas, y otro compilador.

-Se puede adaptar kbd.c?
-Los Pull-down se pueden llegar a eliminar (corto las resistencias)

Tengo la idea que se puede editar esta parte pero no se me ocurre como:
PHP:
#if defined(__PCH__) 
#if defined use_portb_kbd 
   #byte kbd = 0xF81                   // This puts the entire structure 
#else 
   #byte kbd = 0xF83                   // This puts the entire structure 
#endif 
#else 
#if defined use_portb_kbd 
   #byte kbd = 6                  // on to port B (at address 6) 
#else 
   #byte kbd = 8                 // on to port D (at address 8) 
#endif 
#endif 

#if defined use_portb_kbd 
   #define set_tris_kbd(x) set_tris_b(x) 
#else 
   #define set_tris_kbd(x) set_tris_d(x) 
#endif

gracias saludos :)
 
hola loloco, me gustaria saber como modificaste la libreria para mandar el dato antes de soltar el push button, ya que tengo un proyecto que necesita del dato antes de soltar el push
te envio un cordial saludo y gracias
 
Tengo pensado modificar la librería kbd.c para adaptarla a un teclado alfanumérico, algo así como de los celulares. Alguien hizo algo parecido que me guíe?
 
Hola tengo un problema con kbd.c el detalle esta en que hay veces que me marca el mismo numero por ejemplo si marco el 6 en la pantalla marca 6 luego marco el 9 y en la pantalla me marca 6 no se porque se da esto no pasa todo el tiempo ya e revisado la programación la conexión y nada
cualquier comentario se los agradezco

Nota: Esto me pasa en el circuito no en el emulador.
 
Última edición:
Hola a todos. Estoy usando un PIC16F877A con un oscilador a cristal 4.3587MHz con dos Capacitores de 20pF. un teclado 4X3 conectado al puerto B, habilitando el puerto desde la librería.

Noté que las líneas de código que manejan el dato devuelto por la por al función j=kbd_getc(); lo hacen de forma correcta, pero el dato regresado por la función j=kbd_getc() lo regresa errado, a veces, no todo el tiempo.

Por ejemplo; si marco 5 veces # y marco luego el 6, el valor devuelto en la variable j es #
Ya he revisado todo y no veo nada malo, lo único que me falta por revisar el el Fuse el cual colocaré mas tarde al igual que el diagrama en proteus porque estoy en el trabajo y el proyecto lo tengo en casa.

Cabe destacar que en el emulador si funciona todo bien, mi problema es en la vida real, por eso sospecho del fuse.

El programa cuenta con mas de 800 líneas, por eso coloco la función que usa la librería del teclado.

Código:
/*Area de libreria*/
#include <LCD.C>
#include <kbd.c>
#include <string.h> 
#use fast_io(a)
  
Función principal


void main()
{
   
   setup_adc_ports(NO_ANALOGS);
   setup_adc(ADC_OFF);
   set_tris_a(0x1F);
   setup_psp(PSP_DISABLED);
   setup_spi(SPI_SS_DISABLED);
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);
   lcd_init();
   kbd_init();
   port_b_pullups(true);
   
   while(true)
   {
     llamado a la función  menu_llamada
    }






int menu_llamada ( )
{
 char t ;
   kbd_init();
   t=kbd_getc();
  /* En este punto  ya la variable t  llega con el dato errado*/
 if(t!=0 )
    {
      bell();      
   if(t == '1')
       {
        return 1; 
       } 
   if(t == '2')
       {
         return 2 ; 
       }
   if(t == '3')
  {
   return 3 ; 
  }
   if(t == '4')
  {
   return 4 ; 
  }
   if(t == '5')
  {
   return 5 ; 
  }
   if(t == '6')
  {
   return 6 ; 
  }
   if(t == '7')
  {
   return 7 ; 
  }
   if(t == '8')
  {
   return 8 ; 
  }
   if(t == '9')
  {
   return 9 ; 
  }
   if(t == '0')
  {
   return 0 ; 
  }
   if(t == '*')
  {
   return 14 ; 
  }
   if(t == '#')
  {
 return 13 ; 
  } 
    }

  return 16;
}
Hola de esta forma tengo configurado el fuse les agradezco su ayuda de ante mano
#include <16F877A.h>
#device adc=8

#FUSES NOWDT //No Watch Dog Timer
#FUSES XT //Crystal osc <= 4mhz
#FUSES NOPUT //No Power Up Timer
#FUSES NOPROTECT //Code not protected from reading
#FUSES NODEBUG //No Debug mode for ICD
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD //No EE protection
#FUSES WRT_50% //Lower half of Program Memory is Write Protected

#use delay(clock=4000000)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bi ts=8)

hola ya puse lo que me comentaste si hace falta algo mas me dices la verdad ya no se que pueda ser
gracias
 

Adjuntos

  • diagrama.jpg
    diagrama.jpg
    134.6 KB · Visitas: 25
Última edición por un moderador:
Aquí mencionas usar un cristal de 4.3587MHz.
Hola a todos. Estoy usando un PIC16F877A con un oscilador a cristal 4.3587MHz
Pero aquí estás usando este fuse...
#FUSES XT //Crystal osc <= 4mhz
Y declaras una frecuencia de 4MHz --> "#use delay(clock=4000000)"
XT como lo comentas es para usar un cristal menor o igual a 4MHz. Por lo tanto ese fuse no está bien.
Debes usar el fuse HS para utilizar un cristal de 4.3587MHz.
¿Por qué utilizas un cristal a esa frecuencia?
¿Es por algún tipo de cálculo especial que tienes que hacer en tu programa con esa frecuencia?

Otra cosa; no es necesario que configures todos los módulos del PIC si no los vas a usar.
Algunos módulos no son necesarios que los configures cuando no los vas a usar.
Para ver la inicialización de los registros, lee la hoja de datos y podrás saber que valor toman en el POR (Power On Reset)

La palabra de configuración que te recomiendo es esta:

#fuses NOBROWNOUT
#use delay(crystal = 4.3587MHz)

Si te fijas, el único fuse declarado es _BOREN_OFF (En PIC C = NOBROWNOUT)
Y puede ser omitido si requieres que se produzca un reset por bajo voltaje de alimentación.
"Por defecto este fuse quedará activo mientras no se declare en OFF"

Al usar #use delay(crystal = 4.3587MHz) el compilador sabe que se usará un cristal superior a 4MHz y automáticamente establece el tipo de oscilador (HS) y también establece los demás, que en el PIC16F877A quedarán de esta manera al usar tan solo esta declaración:

OSC = HS
WDTE = OFF
PWRTE = ON
BOREN = OFF
WRT = OFF
LVP = OFF
CPD = OFF
CP = OFF
DEBUG = OFF

Como podrás ver, es una palabra de configuración adecuada para el programa que estás realizando.

Una recomendación para ahorrar pines, es usar el teclado y la pantalla por el mismo puerto.
Éste fragmento de código es para usar ambos por el puerto B en el PIC16F877A:

#define LCD_DATA_PORT getenv("SFR:pORTB")
#include <lcd.c>
#define use_portb_kbd TRUE
#include <kbd.c>

Y debe ser colocado debajo de #use delay()

Prueba de esta forma, es funcional como te menciono y está comprobado.
No olvidar activar los resistores pull-up en el puerto B.

Suerte.
 
Última edición:
Hola como respuesta a lo preguntado, uso ese cristal porque aunque parezca mentira en mi país no e podido conseguir un cristal 4Mhz lo mas parecido es el que mecione 4.3587MHz no hay ningún calculo en especial. En efecto como dices esta mal configurado el manejo del oscilador realice los ajustes necesario con respecto al XT y era HS pero me sigue dando el mismo erro.
Ahora lo que are sera terminar de revisar el Fuse como me indicaste para ver que mas esta mal y te cuente.
 
Realicé los ajustes necesarios con respecto al XT y era HS pero me sigue dando el mismo error.
Ahora lo que haré será terminar de revisar el Fuse como me indicaste para ver que más está mal y te cuente.
El problema no creo que lo tengas con los fuses de la palabra de configuración.
Muy probablemente se deba a un problema de hardware.
Tienes que revisar bien las conexiones del teclado y la distribución de teclas del mismo.

Para que salgas de dudas adjunto un ejemplo funcionando a 4.433619MHz.
No tengo ese cristal que mencionas de 4.3587MHz y para el ejemplo expuesto funciona también al usar uno de 4MHz, ya que no se requiere precisión en la frecuencia de trabajo.

En dado caso que con este ejemplo tengas el mismo problema, entonces debes cambiar el PIC, o verificar que todo esté bien conectado en el circuito, porque este ejemplo funciona físicamente.

Suerte.
 

Adjuntos

  • 16F877A LCD 16x2 y Teclado 3x4.rar
    50.7 KB · Visitas: 51
Hola d@rkbytes siguiendo las observaciones dadas por usted encontré 2 botones defectuosos en el panel de.botones ya los remplase y listo hasta ahora no se a presentado el problema aré un par de pruebas pero por ahora todo bien esperemos siga de esta forma.
Gracias por todo. Cualquier cosa te informó
 
Buenas noches soy nuevo en esto de los programas, estoy interesado en este tipo de problema debido a que necesito seleccionar una temperatura y un voltaje por medio de un teclado matricial 4x3.... ¿ como haria para agregar los valores del teclado a la cadena?
 
Realiza un bucle de cuantos dígitos necesites ingresar y en una matriz almacenas en valor de cada dígito.
Después haces la conversión de la cadena almacenada en la matriz a entero con "atoi", atol" o "atoi32", dependiendo de la longitud requerida.
 
Una recomendación para ahorrar pines, es usar el teclado y la pantalla por el mismo puerto.
Éste fragmento de código es para usar ambos por el puerto B en el PIC16F877A:

#define LCD_DATA_PORT getenv("SFR:pORTB")
#include <lcd.c>
#define use_portb_kbd TRUE
#include <kbd.c>

Y debe ser colocado debajo de #use delay()

Prueba de esta forma, es funcional como te menciono y está comprobado.
No olvidar activar los resistores pull-up en el puerto B.

Suerte.

D@rkbytes una pregunta, si hacemos lo que pones en el ejemplo ya no podremos usar las interrupciones del puertoB verdad? o se puede de alguna manera?

Me refiero a RB0= int_ext y RB4-RB7
 
Saludos.
No, ya no se podrán usar las interrupciones del puerto B, porque se activarían con los datos de la pantalla.
Si requieres usar esas interrupciones, es mejor cambiar la pantalla y el teclado a otro puerto.
 
Saludos.
No, ya no se podrán usar las interrupciones del puerto B, porque se activarían con los datos de la pantalla.
Si requieres usar esas interrupciones, es mejor cambiar la pantalla y el teclado a otro puerto.

Hola D@rkbytes, si se cambia al puertoD las librerias estan adaptadas para dicho puerto o habria que hacer alguna modificacion? venga gracias
 
Atrás
Arriba