Autor Tema: Teclado matricial Flex 4x4 interrupción RB[7-4] + antirebote int_timer0  (Leído 32669 veces)

0 Usuarios y 2 Visitantes están viendo este tema.

Desconectado PalitroqueZ

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5474
    • Electrónica Didacta
El hilo surgió del ejemplo que montó pocher en:

Ejemplito 16F876A: Rastreando un Teclado Matricial 4x4 y enviando a la RS232

tomé ese ejemplo y con varias modificaciones y adaptaciones lo puse a funcionar tal como reza el titulo.

Teclado_flex_change_portb.C

Código: C
  1. /* Teclado4.c  - Conexiones del teclado.
  2.  
  3.    He realizado unas modificaciones en Teclado3.c (así se llamaba el original)
  4.    para optimizar los recursos del uC PIC
  5.    Entre ellos tenemos:
  6.      - todas las variables concernientes a la identificación del teclado,
  7.        se han llevado a constantes (para desocupar RAM)
  8.      - dichas constantes corresponden a la combinación generada por los valores
  9.        que los pines del teclado deben tener, con ello si queremos identificar
  10.        la tecla en otra parte del programa, solo tenemos que localizar la
  11.        etiqueta de constante correspondiente.
  12.      - una vez que se valida un condicional sale inmediatamente de kbd_getc()
  13.        evitando la demora de preguntar por los otros condicionales y por
  14.        consiguiente sale mas pronto de la interrupción.
  15.  
  16.    Autor: Pocher
  17.    Modificación: PalitroqueZ  14-May-2008 11:10am
  18.    
  19.    Este código puede usarse libremente siempre que se mantenga/n y/o respete/n
  20.    el/los credito/s de/los autor/es
  21. *******************************************************************************
  22.  
  23.                  iColumna2
  24.          iColumna0   ^
  25.              ^       |
  26.              |       |
  27.            |---|---|---|---|
  28.   RB4 ---> | 1 | 2 | 3 | A |
  29.            |---|---|---|---|
  30.   RB5 ---> | 4 | 5 | 6 | B |
  31.            |---|---|---|---|
  32.   RB6 ---> | 7 | 8 | 9 | C |
  33.            |---|---|---|---|
  34.   RB7 ---> | * | 0 | # | D |
  35.            |---|---|---|---|
  36.                  ^       ^
  37.                  |       |
  38.                       iColumna3
  39.              iColumna1
  40.  
  41.                  
  42. RB4 = fila0
  43. RB5 = fila1
  44. RB6 = fila2
  45. RB7 = fila3
  46.  
  47. */
  48.  
  49.  
  50. int8 const iLos_Cuatro_MSB_PORTB=0b11110000; // selecciona los 4 MSB
  51. int8 iPuerto_compuesto;
  52.  
  53. //*****************************************************
  54.    
  55.  
  56. int8 const iTecla1=0B11101110; // 0xEE
  57. int8 const iTecla4=0B11011110; // 0xDE
  58. int8 const iTecla7=0B10111110; // 0xBE
  59. int8 const iTeclaAsterisco=0B01111110; // 0x7E
  60.  
  61. int8 const iTecla2=0B11101101; // 0xED
  62. int8 const iTecla5=0B11011101; // 0xDD
  63. int8 const iTecla8=0B10111101; // 0xBD
  64. int8 const iTecla0=0B01111101; // 0x7D
  65.  
  66. int8 const iTecla3=0B11101011; // 0xEB
  67. int8 const iTecla6=0B11011011; // 0xDB
  68. int8 const iTecla9=0B10111011; // 0xBB
  69. int8 const iTeclaNumeral=0B01111011; // 0x7B
  70.  
  71. int8 const iTeclaA=0B11100111; // 0xE7
  72. int8 const iTeclaB=0B11010111; // 0xD7
  73. int8 const iTeclaC=0B10110111; // 0xB7
  74. int8 const iTeclaD=0B01110111; // 0x77
  75.  
  76. //***********************************************************
  77. void  Configurar_iPuerto_compuesto(void);
  78. //***********************************************************
  79. int8 kbd_getc(){
  80.    int8 tecla;
  81.    
  82.      output_low(iColumna0);
  83.      output_high(iColumna1);
  84.      output_high(iColumna2);
  85.      output_high(iColumna3);
  86.      Configurar_iPuerto_compuesto();
  87.      if(iPuerto_compuesto == iTecla1 ){tecla=iTecla1; return tecla;}
  88.      if(iPuerto_compuesto == iTecla4 ){tecla=iTecla4; return tecla;}
  89.      if(iPuerto_compuesto == iTecla7 ){tecla=iTecla7; return tecla;}
  90.      if(iPuerto_compuesto == iTeclaAsterisco ){tecla=iTeclaAsterisco;  return tecla;}
  91.      
  92.      output_high(iColumna0);
  93.      output_low(iColumna1);
  94.      output_high(iColumna2);
  95.      output_high(iColumna3);
  96.      
  97.      Configurar_iPuerto_compuesto();
  98.      if(iPuerto_compuesto == iTecla2 ){tecla=iTecla2; return tecla;}
  99.      if(iPuerto_compuesto == iTecla5 ){tecla=iTecla5; return tecla;}
  100.      if(iPuerto_compuesto == iTecla8 ){tecla=iTecla8; return tecla;}
  101.      if(iPuerto_compuesto == iTecla0 ){tecla=iTecla0; return tecla;}
  102.  
  103.      output_high(iColumna0);
  104.      output_high(iColumna1);;
  105.      output_low(iColumna2);
  106.      output_high(iColumna3);
  107.      
  108.      Configurar_iPuerto_compuesto();
  109.      if(iPuerto_compuesto == iTecla3 ){tecla=iTecla3; return tecla;}
  110.      if(iPuerto_compuesto == iTecla6 ){tecla=iTecla6; return tecla;}
  111.      if(iPuerto_compuesto == iTecla9 ){tecla=iTecla9; return tecla;}
  112.      if(iPuerto_compuesto == iTeclaNumeral ){tecla=iTeclaNumeral; return tecla;}
  113.      
  114.      output_high(iColumna0);
  115.      output_high(iColumna1);
  116.      output_high(iColumna2);
  117.      output_low(iColumna3);
  118.      
  119.      Configurar_iPuerto_compuesto();
  120.      if(iPuerto_compuesto == iTeclaA ){tecla=iTeclaA; return tecla;}
  121.      if(iPuerto_compuesto == iTeclaB ){tecla=iTeclaB; return tecla;}
  122.      if(iPuerto_compuesto == iTeclaC ){tecla=iTeclaC; return tecla;}
  123.      if(iPuerto_compuesto == iTeclaD ){tecla=iTeclaD; return tecla;}
  124. }
  125.  
  126. //**************************************************************
  127. // Aquí se agrupa los bits concerniente a las columnas 1-4 junto
  128. // con RB[7-4] en un solo registro para manejarlo a posteriori
  129. // iPuerto_compuesto = [RB7,RB6,RB5,RB4,columna3,columna2,columna1,columna0]
  130. //**************************************************************
  131. void  Configurar_iPuerto_compuesto(void){
  132.    iPuerto_compuesto=0;
  133.    iPuerto_compuesto = input_b() & iLos_Cuatro_MSB_PORTB;
  134.    iPuerto_compuesto |= (input_state(iColumna3) << 3);
  135.    iPuerto_compuesto |= (input_state(iColumna2) << 2);
  136.    iPuerto_compuesto |= (input_state(iColumna1) << 1);
  137.    iPuerto_compuesto |= input_state(iColumna0);
  138.    
  139. }
  140. //********************************************************************
  141. // iColumna[3-0]=0
  142. //********************************************************************
  143. void Limpiar_Columnas(void){
  144.    output_low(iColumna0);
  145.    output_low(iColumna1);
  146.    output_low(iColumna2);
  147.    output_low(iColumna3);
  148. }


programa ejemplo particular
Código: C
  1. /* v1.0
  2.    Programa ejemplo que hace uso del teclado matricial
  3.    4x4 mediante interrupciones y liberando 4 pines del portb,
  4.    haciendo posible cambiarlas por cualquier pin del uC PIC.
  5.    Los 4 pines liberados corresponden a las columnas que maneja el teclado
  6.    
  7.    Caracteristicas:
  8.    - Cambio de estado en los pines RB[7-4]
  9.    - Retardo antirrebotes por Timer0
  10.    
  11.    con la interrupción por cambio en PORTB, se gestiona el teclado sin tener
  12.    que encerrar todo el programa principal en un bucle.
  13.    
  14.    la interrupción del timer0 sirve para crear un retardo antirrebotes SIN
  15.    hacer demorar la ejecución del programa principal.
  16.    
  17.    el próposito de ambas interrupciones es detectar la pulsación de una
  18.    tecla y garantizar que no sea un falso contacto todo ello sin "detener"
  19.    el bucle principal.
  20.    
  21.    solo se gestionará el proceso correspondiente cuando se pulsa la tecla
  22.    (está validado para no responder a soltar la tecla o mantenerla
  23.     indefinidamente).
  24.    si quiere ejecutar el proceso asociado a la tecla nuevamente, basta pulsar
  25.    otra vez dicha tecla.
  26.  
  27.  
  28.    Autor: Pocher
  29.    Modificación: PalitroqueZ  14-May-2008 11:10am
  30.    
  31.    Este código puede usarse libremente siempre que se mantenga/n y/o respete/n
  32.    el/los credito/s de/los autor/es
  33.  
  34. */
  35.  
  36. #include <18F4550.h>
  37. #fuses XTPLL,NOMCLR,NOWDT,NOPROTECT,
  38. #fuses NOLVP,NODEBUG,NOPBADEN,USBDIV,PLL1
  39. #fuses CPUDIV1,NOVREGEN,NOIESO // IESO bit ignorado
  40. #use delay(clock=48M)
  41.  
  42. #use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7) // opcional
  43.  
  44. #use fast_io(A)   // opcional
  45. #use fast_io(B)   //    "
  46. #use fast_io(C)   //    "
  47. #use fast_io(D)   //    "
  48. #use fast_io(E)   //    "
  49.  
  50. #byte PORTB=0xF81
  51. // declarar la dirección del portb
  52.  
  53. //*********************************
  54. // variables globales
  55. //*********************************
  56.  
  57. int8 const iVeces_iContador_1ms=30;
  58. int8 iFlanco_RB=0;  // bandera que detecta el primer flanco del pulsador
  59. int8 iContador_1ms=0;  // con Fcpu=48MHz, el timer0 cuenta máximo ~ 5ms
  60. int8 iTecla_capturada=0;
  61. int1 fImprimir=0;  // Bandera ejemplo para imprimir tecla presionada
  62.  
  63. #define iColumna0   PIN_D7
  64. #define iColumna1   PIN_C2
  65. #define iColumna2   PIN_A0
  66. #define iColumna3   PIN_D0
  67.  
  68. //*********************************
  69. // archivos a incluir
  70. //*********************************
  71. #include "Teclado_flex_change_portb.C"
  72. //----------------------------------------------------
  73. #int_timer0
  74. void  tmr0_isr(){
  75. int8 temp;
  76.  
  77.    if(iContador_1ms==iVeces_iContador_1ms){  
  78.       // retardo antirebotes = 1ms * iVeces_iContador_1ms
  79.       // ya pasaron 30 ms después de la interrupción
  80.       // por cambio de PORTB (el retardo puede variarse)
  81.       temp = input_b() & iLos_Cuatro_MSB_PORTB;
  82.       if(iFlanco_RB == temp){
  83.       // pregunta si realmente la tecla se pulsó
  84.       // o por el contrario es un falso contacto
  85.      
  86.       // aqui es donde se procesa la tecla para lo que queramos hacer
  87.          iTecla_capturada=kbd_getc();
  88.          fImprimir=1;
  89.        }
  90.       Limpiar_Columnas();
  91.       iContador_1ms=0;
  92.       disable_interrupts(INT_TIMER0);
  93.       #asm movf PORTB,0 #endasm
  94.       clear_interrupt(int_rb); // RBIF = 0 limpia la bandera
  95.       enable_interrupts(int_rb);
  96.    }else{
  97.       iContador_1ms++;
  98.       // continua el miniretardo que es multiplo de retardo deseado
  99.    }
  100. }
  101. //----------------------------------------------------
  102. #int_rb // Interrupcion cambio de estado RB[4-7]
  103. void control_rb() {
  104.    iFlanco_RB = input_b() & iLos_Cuatro_MSB_PORTB;
  105.    // almacena el valor de RB[7-4] inicial
  106.    if(iFlanco_RB != iLos_Cuatro_MSB_PORTB){
  107.       // este condicional sirve para validar cuando se pulsa
  108.       // la tecla (mas NO cuando se suelta).
  109.       // consume 4 lineas de asm.
  110.       disable_interrupts(INT_RB);
  111.       // deselecciona la interrupción por cambio en PORTB
  112.       // para comenzar el retardo antirebote
  113.       iContador_1ms=0;
  114.       setup_timer_0(RTCC_INTERNAL|RTCC_DIV_64|RTCC_8_BIT);
  115.       // configura el Timer0 base de tiempo interno, pre-escaler=1:256
  116.       set_timer0(68); // retardo de ~ 1ms
  117.       enable_interrupts(INT_TIMER0);
  118.    }
  119.    #asm movf PORTB,0 #endasm
  120.    Limpiar_Columnas();
  121. }
  122.  
  123. //--------------------------------------------------
  124. void main() {
  125.    output_a(0);
  126.    output_b(0);
  127.    output_c(0);
  128.    output_d(0);
  129.    output_e(0);
  130.    
  131.    set_tris_a(0x0);
  132.    set_tris_b(0b11110000);  // RB[7-4] son entradas
  133.    set_tris_c(0x0);
  134.    set_tris_d(0x0);
  135.    set_tris_e(0x0);
  136.    
  137.    port_b_pullups(true);  
  138.    // no es obligatorio. Si es false, se colocan pull-up externas en RB[7-4]
  139.    disable_interrupts(global);
  140.    disable_interrupts(INT_TIMER0);
  141.  
  142.    printf("Preparando al teclado por interrupcion (int_RB)\n\r");
  143.  
  144.    Limpiar_Columnas();
  145.    
  146.    enable_interrupts(int_rb);
  147.    #asm movf PORTB,0 #endasm  // con estas 2 lineas, se borra
  148.    clear_interrupt(INT_RB);   // RBIF al inicio del programa
  149.    enable_interrupts(global);
  150.    
  151.    while(1){
  152.       if(fImprimir){
  153.          printf("interrupcion: %x\n\r",iTecla_capturada);
  154.          iTecla_capturada=0;
  155.          fImprimir=0;
  156.       }
  157.    }
  158.    
  159. }

plantilla de ejemplo (template)

Código: C
  1. #include <1xFxxxx.h>
  2. #fuses XT,NOMCLR,NOWDT,NOPROTECT,
  3. #fuses NOLVP,NODEBUG,PUT
  4.  
  5. #use delay(clock=4M)
  6.  
  7. #byte PORTB=0xAAA
  8. // buscar en la datasheet el valor correspondiente a la dirección del portb
  9.  
  10. //*********************************
  11. // variables globales
  12. //*********************************
  13.  
  14. int8 const iVeces_iContador_1ms=30;  // 30ms. Varía de acuerdo a Fosc
  15. int8 iFlanco_RB=0;  // bandera que detecta el primer flanco del pulsador
  16. int8 iContador_1ms=0;  
  17. int8 iTecla_capturada=0;
  18.  
  19. #define iColumna0   PIN_Xn  // defina los pines de elección
  20. #define iColumna1   PIN_Xn
  21. #define iColumna2   PIN_Xn
  22. #define iColumna3   PIN_Xn
  23.  
  24. //*********************************
  25. // archivos a incluir
  26. //*********************************
  27. #include "Teclado_flex_change_portb.C"
  28. //----------------------------------------------------
  29. #int_timer0
  30. void  tmr0_isr(){
  31. int8 temp;
  32.    if(iContador_1ms==iVeces_iContador_1ms){  
  33.       // retardo antirebotes = 1ms * iVeces_iContador_1ms
  34.       // ya pasaron 30 ms después de la interrupción
  35.       // por cambio de PORTB (el retardo puede variarse)
  36.       temp = input_b() & iLos_Cuatro_MSB_PORTB;
  37.       if(iFlanco_RB == temp){
  38.       // pregunta si realmente la tecla se pulsó
  39.       // o por el contrario es un falso contacto
  40.      
  41.       // aqui es donde se procesa la tecla para lo que queramos hacer
  42.          iTecla_capturada=kbd_getc();
  43.        }
  44.       Limpiar_Columnas();
  45.       iContador_1ms=0;
  46.       disable_interrupts(INT_TIMER0);
  47.       #asm movf PORTB,0 #endasm
  48.       clear_interrupt(int_rb); // RBIF = 0 limpia la bandera
  49.       enable_interrupts(int_rb);
  50.    }else{
  51.       iContador_1ms++;
  52.       // continua el miniretardo que es multiplo de retardo deseado
  53.    }
  54. }
  55. //----------------------------------------------------
  56. #int_rb // Interrupcion cambio de estado RB[4-7]
  57. void control_rb() {
  58.    iFlanco_RB= PORTB & iLos_Cuatro_MSB_PORTB;
  59.    // almacena el valor de RB[7-4] inicial
  60.    if(iFlanco_RB != iLos_Cuatro_MSB_PORTB){
  61.       // este condicional sirve para validar cuando se pulsa
  62.       // la tecla (mas NO cuando se suelta).
  63.       // consume 4 lineas de asm.
  64.       disable_interrupts(INT_RB);
  65.       // deselecciona la interrupción por cambio en PORTB
  66.       // para comenzar el retardo antirebote
  67.       iContador_1ms=0;
  68.       setup_timer_0(RTCC_INTERNAL|RTCC_DIV_64|RTCC_8_BIT);
  69.       // configura el Timer0 base de tiempo interno, pre-escaler=1:256
  70.       set_timer0(68); // retardo de ~ 1ms. Varía de acuerdo a Fosc
  71.       enable_interrupts(INT_TIMER0);
  72.    }
  73.    #asm movf PORTB,0 #endasm
  74.    Limpiar_Columnas();
  75. }
  76.  
  77. //--------------------------------------------------
  78. void main() {
  79.    //...
  80.    output_b(0);
  81.    //...
  82.    set_tris_b(0b11110000);  // RB[7-4] son entradas
  83.    // los pines correspondiente a las columnas deben ser salidas
  84.    //...
  85.    port_b_pullups(true);  
  86.    // no es obligatorio. Si es false, se colocan pull-up externas en RB[7-4]
  87.    disable_interrupts(global);
  88.    disable_interrupts(INT_TIMER0);
  89.  
  90.    Limpiar_Columnas();
  91.    
  92.    enable_interrupts(int_rb);
  93.    #asm movf PORTB,0 #endasm  // con estas 2 lineas, se borra
  94.    clear_interrupt(INT_RB);   // RBIF al inicio del programa
  95.    enable_interrupts(global);
  96.    //...
  97.    //...
  98.    while(1){
  99.         //...
  100.         // aquí se procesa a iTecla_capturada
  101.         //...
  102.       }
  103. }


imagen del circuito:



pura interrupción, ahora lo tengo de moda, nada de perdedera de tiempo metido en bucles "inutiles" cuando se cuenta con herramientas como int_rb e int_timer. Hace todo el rastreo del teclado CUANDO DEBE HACERLO, y luego el contador de programas vuelve a su bucle principal y deja el sistema (int_rb and int_timer) listo y calentito para cuando algún humano se le ocurra presionar una tecla otra vez jijiji

y otra cosa super importante, libera los 4 pines LSB del portb que suponen las columnas del teclado, y se pueden definir como cualquier otros pines independientes y de cualquier puerto (siempre que sean salidas)

Hasta la fecha NO he probado este código en Físico, puesto que no cuento con las 16 teclas necesarias. Pero hice una variante de este programa para 7 teclas y con el mismo método de interrupción RB[7-4] + timer0 y funcionó correctamente en el protoboard.

bajar adjunto
     
pd: Disfruté escribiendo este programa y el agradecimiento al maestro pocher por su programa ;)
La propiedad privada es la mayor garantía de libertad.
Friedrich August von Hayek

Desconectado jfh900

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 3595
Re: Teclado matricial Flex 4x4 interrupción RB[7-4] + antirebote int_timer0
« Respuesta #1 en: 14 de Mayo de 2008, 16:49:36 »
Excelente trabajo Pedro.

Una cuestión: ¿no se podría incluir la/s interrupción/es dentro de la librería?.

La idea es mediante el preprocesador verificar que no se ha asignado las interrupciones (y si esto sucede dar un mensaje de error) y asignar la interrupción dentro de la librería.

Un saludo
* Cuando hables, procura que tus palabras sean mejores que el silencio.
* 'Todos somos ignorantes, lo que ocurre es que no todos ignoramos las mismas cosas.' Albert Einstein.
* No hay nada peor que un experto para evitar el progreso en un campo
* "La vida es como una novela. No importa que sea larga, sino que esté bien narrada" Seneca
* La vida no se vive por las veces que respiras, sino por los momentos que dejan sin aliento.
* Dios dijo: ∇·E=ρ/ε0 ; ∇·B=0 ; ∇xE=-dB/dt ; ∇xB= μ0ε0dE/dt..y la luz se hizo..!!..

Desde España Jesús

Desconectado PalitroqueZ

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5474
    • Electrónica Didacta
Re: Teclado matricial Flex 4x4 interrupción RB[7-4] + antirebote int_timer0
« Respuesta #2 en: 15 de Mayo de 2008, 15:03:43 »
podría ser.

Al driver le hecho como una docena de cambios. Siempre tratando de mejorarla.

int_rb puede entrar bien en el driver, el timer si y no. porque si lo vamos a utilizar en otros procesos, debería ser visible en el main.

no creo que ocurran choques entre interrupciones, ya que se desactiva uno justo cuando comienza el otro.

hay que pensar en todos los casos posibles para hacerlo generalizado, uff.  :)



La propiedad privada es la mayor garantía de libertad.
Friedrich August von Hayek

Desconectado Nocturno

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 18286
    • MicroPIC
Re: Teclado matricial Flex 4x4 interrupción RB[7-4] + antirebote int_timer0
« Respuesta #3 en: 15 de Mayo de 2008, 15:09:04 »
Me encanta; muchas gracias Pedro.

La sugerencia de Jesús es muy buena, pero también te entiendo a ti: siempre se puede mejorar algo, pero en ese caso nunca acabarías  :D

Desconectado pocher

  • Moderador Local
  • DsPIC30
  • *****
  • Mensajes: 2568
Re: Teclado matricial Flex 4x4 interrupción RB[7-4] + antirebote int_timer0
« Respuesta #4 en: 16 de Mayo de 2008, 04:15:00 »
Gracias por el programa Pali.

Ayer lo descargué y le hice algunas modificaciones para probarlo en un teclado real, con un 16F876 y una LCD.

Hoy por la mañana he terminado de hacer todas las pruebas tanto con PROTEUS como físicamente y va muy bien. Solo un pequeño pero, para que aparezca la tecla debes de estar apretando demasiado tiempo, ocurre tanto con PROTEUS como en real.

Me pongo y subo el archivo con la simulación: con un 16F876, un teclado de 16 teclas y una LCD. Tanto el teclado como la LCD, todo conectado al PORTB.

Un saludo

Desconectado pocher

  • Moderador Local
  • DsPIC30
  • *****
  • Mensajes: 2568
Re: Teclado matricial Flex 4x4 interrupción RB[7-4] + antirebote int_timer0
« Respuesta #5 en: 16 de Mayo de 2008, 05:59:46 »
Me he demorado un poco en subirlo porque estaba dándole vueltas a lo del retraso y ya lo solucioné.

Lo estaba probando con un cristal de 4Mhz (el que tengo aquí) y con este va lento. He hecho la prueba en PROTEUS cambiando en la programación a 20MHZ y va como un tiro. :-/

Aquí debajo os dejo todos los archivos.

Desconectado PalitroqueZ

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5474
    • Electrónica Didacta
Re: Teclado matricial Flex 4x4 interrupción RB[7-4] + antirebote int_timer0
« Respuesta #6 en: 19 de Mayo de 2008, 12:32:16 »
pocher revisé lo que subiste, dejame decirte que está interesante ese caso ;)

lo digo porque usas RB[7-4] para enviar datos a la lcd, en tal condición el flag RBIF se activará a partir del primer cambio portb originado por el primer nibble enviado a la pantalla.

no se cuál seran las consecuencias si cuando manda a imprimir al lcd, presiono una tecla. Por si las moscas, es mejor deshabilitar INT_RB al momento de usar lcd_putc y limpiar las columnas.

quedaría así:

Código: C
  1. ...
  2.    while(1){
  3.       if(fImprimir){
  4.          printf("interrupcion: %x\n\r",iTecla_capturada);
  5.          
  6.          disable_interrupts(INT_RB);
  7.          set_tris_b(0x0F);         //Activar LCD
  8.          lcd_gotoxy(1,1);
  9.          printf(lcd_putc,"interrupcion: %x",iTecla_capturada);
  10.          lcd_gotoxy(1,2);
  11.          for(n=0;n<16;n++)
  12.          {
  13.                if(iTecla_capturada==a[n])      printf(lcd_putc,"Tecla=%c",b[n]);
  14.              }
  15.          set_tris_b(0xF0);         //Activar teclado
  16.          
  17.          iTecla_capturada=0;
  18.          fImprimir=0;
  19.          Limpiar_Columnas();
  20.          #asm movf PORTB,0 #endasm  // con estas 2 lineas, se borra
  21.          clear_interrupt(INT_RB);   // RBIF al inicio del programa
  22.          enable_interrupts(int_rb);
  23.  
  24.       }
  25.    }

lo otro: Se te olvidó configurar el timer0 para el nuevo cristal (1 ms -> TMR0=6 con prescaler: 4 )

podría ponerse una ecuación para que el mismo programa calcule el dato en timer0, pero lo veo dificil, porque también involucra al prescaler, y todas las combinaciones que conlleva (sin sumar todos los distintos cristales que el usuario vaya usar)

Cuando tengas un tiempito, pruéba el programa modificado en físico, a ver que tal.

bajar adjunto:
La propiedad privada es la mayor garantía de libertad.
Friedrich August von Hayek

Desconectado pocher

  • Moderador Local
  • DsPIC30
  • *****
  • Mensajes: 2568
Re: Teclado matricial Flex 4x4 interrupción RB[7-4] + antirebote int_timer0
« Respuesta #7 en: 20 de Mayo de 2008, 08:47:22 »
Sí, se me olvidó ... a los programas solo los entiende la madre (padre) que los parió.  :D

Oye que lo he probado en físico con 4 Mhz y ahora sí que va bien, la tecla aparece rápidamente en pantalla. Totalmente de acuerdo con las mejoras que le has introducido ahora, más vale prevenir.

Un saludo Pali.

Desconectado jfh900

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 3595
Re: Teclado matricial Flex 4x4 interrupción RB[7-4] + antirebote int_timer0
« Respuesta #8 en: 21 de Mayo de 2008, 04:57:33 »
lo otro: Se te olvidó configurar el timer0 para el nuevo cristal (1 ms -> TMR0=6 con prescaler: 4 )

podría ponerse una ecuación para que el mismo programa calcule el dato en timer0, pero lo veo dificil, porque también involucra al prescaler, y todas las combinaciones que conlleva (sin sumar todos los distintos cristales que el usuario vaya usar)

¿Por qué no utilizais el preprocesador para seleccionar el reloj y el preescalar?

Un saludo
* Cuando hables, procura que tus palabras sean mejores que el silencio.
* 'Todos somos ignorantes, lo que ocurre es que no todos ignoramos las mismas cosas.' Albert Einstein.
* No hay nada peor que un experto para evitar el progreso en un campo
* "La vida es como una novela. No importa que sea larga, sino que esté bien narrada" Seneca
* La vida no se vive por las veces que respiras, sino por los momentos que dejan sin aliento.
* Dios dijo: ∇·E=ρ/ε0 ; ∇·B=0 ; ∇xE=-dB/dt ; ∇xB= μ0ε0dE/dt..y la luz se hizo..!!..

Desde España Jesús

Desconectado PalitroqueZ

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5474
    • Electrónica Didacta
Re: Teclado matricial Flex 4x4 interrupción RB[7-4] + antirebote int_timer0
« Respuesta #9 en: 21 de Mayo de 2008, 12:55:38 »
tendré que averiguar que significa


La propiedad privada es la mayor garantía de libertad.
Friedrich August von Hayek

Desconectado pocher

  • Moderador Local
  • DsPIC30
  • *****
  • Mensajes: 2568
Re: Teclado matricial Flex 4x4 interrupción RB[7-4] + antirebote int_timer0
« Respuesta #10 en: 21 de Mayo de 2008, 13:38:29 »
Sí, supongo que Jesús se refiere a sentencias #IFDEF #IFNDEF #ELSE etc

Sería una mejora más.

Aprovecho ahora Pali para comentarte que pensaré lo del fallo del antirebotes software, a ver si lo sacamos.

Un saludo

Desconectado jfh900

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 3595
Re: Teclado matricial Flex 4x4 interrupción RB[7-4] + antirebote int_timer0
« Respuesta #11 en: 21 de Mayo de 2008, 16:46:11 »
Efectivamente a eso me refería, que definiendo una variable del preprocesador, se ajustaran los parámetros y no se tenga que variar medio programa.

Un saludo
* Cuando hables, procura que tus palabras sean mejores que el silencio.
* 'Todos somos ignorantes, lo que ocurre es que no todos ignoramos las mismas cosas.' Albert Einstein.
* No hay nada peor que un experto para evitar el progreso en un campo
* "La vida es como una novela. No importa que sea larga, sino que esté bien narrada" Seneca
* La vida no se vive por las veces que respiras, sino por los momentos que dejan sin aliento.
* Dios dijo: ∇·E=ρ/ε0 ; ∇·B=0 ; ∇xE=-dB/dt ; ∇xB= μ0ε0dE/dt..y la luz se hizo..!!..

Desde España Jesús

Desconectado PalitroqueZ

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5474
    • Electrónica Didacta
Re: Teclado matricial Flex 4x4 interrupción RB[7-4] + antirebote int_timer0
« Respuesta #12 en: 21 de Mayo de 2008, 17:37:33 »
ah entonces ya me pongo a ello.  :mrgreen:



La propiedad privada es la mayor garantía de libertad.
Friedrich August von Hayek

Desconectado PalitroqueZ

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5474
    • Electrónica Didacta
Re: Teclado matricial Flex 4x4 interrupción RB[7-4] + antirebote int_timer0
« Respuesta #13 en: 02 de Junio de 2008, 16:48:30 »
Hola, me he puesto ha mejorar el "driver" para escribir menos a la hora de usarlo en un programa particular.

he tomado la sugerencia de Jesús, en cuanto a pre-procesar las interrupciones, pero no he hallado una solución.

por ejemplo: se pretende que el compilador detecte una segunda #int_rb

siguiendo la ayuda, coloqué

Código: C
  1. ...
  2. #if defined(INT_RB)
  3.    #error  La Interrupcion por cambio en PORTB, viene incluida en Teclado_flex_change_portb
  4. #else
  5. #int_rb
  6. void control_rb() {
  7.    iFlanco_RB = input_b() & iLos_Cuatro_MSB_PORTB;
  8. ..
  9. #endif
  10. ...

pero siempre va directo al error, probé con #ifndef, igual. si no coloco eso, el compilador si detectará la doble interrupción (error 92) pero no me indicará donde está la otra (que era precisamente que señalaría #error).

La propiedad privada es la mayor garantía de libertad.
Friedrich August von Hayek

Desconectado Cryn

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 4169
Re: Teclado matricial Flex 4x4 interrupción RB[7-4] + antirebote int_timer0
« Respuesta #14 en: 11 de Octubre de 2008, 12:02:18 »
es una muy buena aplicacion, he estado intentando hacer uno parecido, tb por interrupcion en RB, y usando el timer 1 para rotar un cero para que sea recibido en el nible alto de RB.

Segun he visto tu codigo no hace rotar ningun cero, solamente explora la interrupcion RB y ahí directamente analiza donde ha sido pulsado, es esto correcto o me equivoco?

Si fuera así sería muy interesante, pues usas 2 interrupciones (rb y tmr0 antirrebote); ya que yo usaría 3, rb, tmr1 para rotar y tmr2 para antirrebote, que me parece un desperdicio de recursos por mi parte.

Cuentame un detalle más, que pasa en el antirrebote, me parecio entender que hay un retardo de una cantidad x de milisegundos, y despues recien se ejecuta la detección de la tecla pulsada. Y como reacciona tu codigo ante teclas manteniendose presionadas??

Muchas gracias por el aporte, está buenísimo.
.


 

anything