TODOPIC

Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: AngelGris en 21 de Noviembre de 2010, 15:18:49

Título: Subo libreria para teclados en HiTech
Publicado por: AngelGris en 21 de Noviembre de 2010, 15:18:49
  Aquí les dejo esta librería para HiTEch. Sólo existe la función GetKey() pero se la puede configurar para distintos tipos de teclados y también configurar si se va a utilizar resistencias de pull-up o pull-down

Código: C
  1. /**************************************************************************
  2. *        Librerira para manejar teclados 3x4 y 4x4 para Hitech            *
  3. ***************************************************************************
  4.  
  5. ***************************************************************************
  6. * El puerto de entrada puede estar con resistencias de Pull-up o con      *
  7. * resistencias de Pull-Down.                                              *
  8. ***************************************************************************
  9.  
  10. ***************************************************************************
  11. *                                                                         *
  12. * Antes de incluir este archivo en nuestro programa hay que definir       *
  13. * algunos parametros. Estos son                                           *
  14. *                                                                         *
  15. * KeyOutPort       (el puerto que se utilizara como salida)               *
  16. * KeyInPort        (el puerto que se utilizara como entrada)              *
  17. * OutD0            (el primer bit de salida)                              *
  18. * InD0             (el primer bit de entrada)                             *
  19. *                                                                         *
  20. * Segun el teclado a utilizar hay que definir PHONE HEXA u OTRO           *
  21. * Si el tipo de teclado es PHONE OutD0 puede tomar los siguientes valores *
  22. * 0, 1, 4 o 5. InD0 puede ser 0 o 4                                       *
  23. *                                                                         *
  24. * Para teclados del tipo HEXA u OTRO OutD0 e InD0 solo pueden ser 0 o 4   *
  25. *                                                                         *
  26. * Si se van utilizar resistencias de Pull-up hay que definir PULLUP       *
  27. * Si se van utilizar resistencias de Pull-Down hay que definir PULLDOWN   *
  28. *                                                                         *
  29. ***************************************************************************
  30.  
  31. ***************************************************************************
  32. * La unica funcion disponible es GetKey y devuelve el codigo ASCII de la  *
  33. * tecla precionada                                                        *
  34. ***************************************************************************
  35.  
  36. ***************************************************************************
  37. *                      Disposicion de teclados                            *
  38. *                                                                         *
  39. * Como los unicos bits definidos son OutD0 e InD0, el resto de los bits   *
  40. * se usan a partir del D0. Es decir, si definimos OutD0 1 quiere decir    *
  41. * que OutD0 tiene que estar conectado al bit 1 del puerto elegido, de     *
  42. * esta forma OutD1 tiene que ir conectado al bit 2 y OutD2 al bit 3       *
  43. * El mismo razonamiento se utiliza para los bits de entrada               *
  44. ***************************************************************************
  45.  
  46.  
  47. ***************************************************************************
  48. *                           PHONE                                         *
  49. *                                                                         *
  50. *                    OutD0   OutD1   OutD2                                *
  51. *                      |       |       |                                  *
  52. *                     ---     ---     ---                                 *
  53. *            InD0 ---| 1 |---| 2 |---| 3 |                                *
  54. *                     ---     ---     ---                                 *
  55. *                      |       |       |                                  *
  56. *                     ---     ---     ---                                 *
  57. *            InD1 ---| 4 |---| 5 |---| 6 |                                *
  58. *                     ---     ---     ---                                 *
  59. *                      |       |       |                                  *
  60. *                     ---     ---     ---                                 *
  61. *            InD2 ---| 7 |---| 8 |---| 9 |                                *
  62. *                     ---     ---     ---                                 *
  63. *                      |       |       |                                  *
  64. *                     ---     ---     ---                                 *
  65. *            InD3 ---| * |---| 0 |---| # |                                *
  66. *                     ---     ---     ---                                 *
  67. *                                                                         *
  68. ***************************************************************************
  69.  
  70. ***************************************************************************
  71. *                               HEXA                                      *
  72. *                                                                         *
  73. *                    OutD0   OutD1   OutD2   OutD3                        *
  74. *                      |       |       |       |                          *
  75. *                     ---     ---     ---     ---                         *
  76. *            InD0 ---| 0 |---| 1 |---| 2 |---| 3 |                        *
  77. *                     ---     ---     ---     ---                         *
  78. *                      |       |       |       |                          *
  79. *                     ---     ---     ---     ---                         *
  80. *            InD1 ---| 4 |---| 5 |---| 6 |---| 7 |                        *
  81. *                     ---     ---     ---     ---                         *
  82. *                      |       |       |       |                          *
  83. *                     ---     ---     ---     ---                         *
  84. *            InD2 ---| 8 |---| 9 |---| A |---| B |                        *
  85. *                     ---     ---     ---     ---                         *
  86. *                      |       |       |       |                          *
  87. *                     ---     ---     ---     ---                         *
  88. *            InD3 ---| C |---| D |---| E |---| F |                        *
  89. *                     ---     ---     ---     ---                         *
  90. *                                                                         *
  91. ***************************************************************************
  92.  
  93. ***************************************************************************
  94. *                               OTRO                                      *
  95. *                                                                         *
  96. *                    OutD0   OutD1   OutD2   OutD3                        *
  97. *                      |       |       |       |                          *
  98. *                     ---     ---     ---     ---                         *
  99. *            InD0 ---| 1 |---| 2 |---| 3 |---| A |                        *
  100. *                     ---     ---     ---     ---                         *
  101. *                      |       |       |       |                          *
  102. *                     ---     ---     ---     ---                         *
  103. *            InD1 ---| 4 |---| 5 |---| 6 |---| B |                        *
  104. *                     ---     ---     ---     ---                         *
  105. *                      |       |       |       |                          *
  106. *                     ---     ---     ---     ---                         *
  107. *            InD2 ---| 7 |---| 8 |---| 9 |---| C |                        *
  108. *                     ---     ---     ---     ---                         *
  109. *                      |       |       |       |                          *
  110. *                     ---     ---     ---     ---                         *
  111. *            InD3 ---| * |---| 0 |---| # |---| D |                        *
  112. *                     ---     ---     ---     ---                         *
  113. *                                                                         *
  114. ***************************************************************************
  115.  
  116. * Ejemplo de configuración y utilización
  117.  
  118.  Se usa un teclado tipo PHONE, se leen los datos por el nibble alto del puerto B
  119.  con resistencias de pull-down
  120.  y para la salida hacia el teclado se usa parte del nibble bajo del puerto A
  121.  
  122.  En un PIC 16F876A
  123.  
  124.  
  125.  #define PHONE
  126.  #define PULLDOWN
  127.  #define KeyOutPort PORTA
  128.  #define KeyInPort  PORTB
  129.  #define OutD0      0
  130.  #define InD0       4
  131.  
  132.  #include "Teclados.c"
  133.  
  134.  
  135.  void main (void)
  136.  {
  137.    unsigned char Tecla_pulsada;
  138.  
  139.    CMCON = 7;          // desactivo los comparadores
  140.    ADON = 0;           // apago el conversor AD
  141.    ADCON1 =  0x07;     // entradas digitales
  142.  
  143.    TRISB = 0xF0;       // el nibble alto como entrada
  144.    TRISA = 0;          // puerto como salida
  145.    TRISC = 0;          // puerto C como salida
  146.    PORTC = 0;
  147.    PORTA = 0x07;       // salidas del puerto A en "1"
  148.  
  149.    while (1)
  150.    {
  151.      if ((PORTB & 0xF0) != 0) //si hay alguna tecla presionada
  152.      {
  153.        // alguna rutina de espera de unos 10ms para Antirebote
  154.        if ((PORTB & 0xF0) != 0) si sigue presionada
  155.        {
  156.          Tecla_pulsada = GetKey();  //leeo el teclado
  157.          if (Tecla_pulsada != 0) PORTC = Tecla_pulsada; // muestro en el puerto C el valor leido
  158.        }
  159.      }
  160.    }
  161.  }
  162.  
  163.  
  164.  
  165. */
  166.  
  167. #if (defined (KeyOutPort) && defined (KeyInPort) && defined (OutD0) && defined (InD0)) \
  168.     && (defined (PHONE) || defined (HEXA) || defined (OTRO)) && \
  169.     (defined (PULLUP) || defined (PULLDOWN))
  170.  
  171.   #if defined (PHONE)
  172.     const unsigned char AsciiKey [4][3] = {'1','2','3','4','5','6','7','8','9','*','0','#'};
  173.  
  174.     unsigned char GetKey (void)
  175.     {    
  176.       unsigned char key;
  177.       unsigned char fila = 0;
  178.       unsigned char columna = 0;  
  179.  
  180.       #if defined (PULLDOWN)
  181.         do
  182.         {
  183.           #if (OutD0 == 0)
  184.             KeyOutPort &= 0b11111000;
  185.             KeyOutPort |= (1 << columna);
  186.           #elif (OutD0 == 1)
  187.             KeyOutPort &= 0b11110001;
  188.             KeyOutPort |= (1 << (columna + 1));
  189.           #elif (OutD0 == 4)
  190.             KeyOutPort &= 0b10001111;
  191.             KeyOutPort |= (1 << (columna + 4));
  192.           #elif (OutD0 == 5)
  193.             KeyOutPort &= 0b00011111;
  194.             KeyOutPort |= (1 << (columna + 5));
  195.           #endif
  196.           #if (InD0 == 0)
  197.             key = PORTB & 0x0F;
  198.           #elif (InD0 == 4)
  199.             key = PORTB & 0xF0;
  200.             key = key >> 4;
  201.           #endif
  202.           columna++;
  203.         }
  204.         while ((key == 0) && (columna < 3));
  205.         if (key == 1) fila = 0;
  206.         else
  207.           if (key == 2) fila = 1;
  208.           else
  209.             if (key == 4) fila = 2;
  210.             else
  211.               if (key == 8) fila = 3;
  212.         #if (OutD0 == 0)
  213.           KeyOutPort |= 0b00000111;
  214.         #elif (OutD0 == 1)
  215.           KeyOutPort |= 0b00001110;
  216.         #elif (OutD0 == 4)
  217.           KeyOutPort |= 0b01110000;
  218.         #elif (OutD0 == 5)
  219.           KeyOutPort |= 0b11100000;
  220.         #endif
  221.         if (key != 0) return AsciiKey[fila][columna - 1];
  222.  
  223.      #elif defined (PULLUP)
  224.         do
  225.         {
  226.           #if (OutD0 == 0)
  227.             KeyOutPort |= 0b00000111;
  228.             KeyOutPort &= ~(1 << columna);
  229.           #elif (OutD0 == 1)
  230.             KeyOutPort |= 0b00001110;
  231.             KeyOutPort &= ~(1 << (columna + 1));
  232.           #elif (OutD0 == 4)
  233.             KeyOutPort |= 0b01110000;
  234.             KeyOutPort &= ~(1 << (columna + 4));
  235.           #elif (OutD0 == 5)
  236.             KeyOutPort |= 0b11100000;
  237.             KeyOutPort &= ~(1 << (columna + 5));
  238.           #endif  
  239.           #if (InD0 == 0)
  240.             key = PORTB & 0x0F;
  241.           #elif (InD0 == 4)
  242.             key = PORTB & 0xF0;
  243.             key = key >> 4;
  244.           #endif
  245.           columna++;
  246.         }
  247.         while ((key == 0x0F) && (columna < 3));
  248.         if (key == 0b00001110) fila = 0;
  249.         else
  250.           if (key == 0b00001101) fila = 1;
  251.           else
  252.             if (key == 0b00001011) fila = 2;
  253.             else
  254.               if (key == 0b00000111) fila = 3;
  255.         #if (OutD0 == 0)
  256.           KeyOutPort &= 0b11111000;
  257.         #elif (OutD0 == 1)
  258.           KeyOutPort &= 0b11110001;
  259.         #elif (OutD0 == 4)
  260.           KeyOutPort &= 0b10001111;
  261.         #elif (OutD0 == 5)
  262.           KeyOutPort &= 0b00011111;
  263.         #endif
  264.         if (key != 0x0F) return AsciiKey[fila][columna - 1];
  265.       #endif
  266.       return 0;
  267.     }
  268.  
  269.   #elif defined (HEXA)
  270.     const unsigned char AsciiKey [4][4] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
  271.  
  272.     unsigned char GetKey (void)
  273.     {    
  274.       unsigned char key;
  275.       unsigned char fila = 0;
  276.       unsigned char columna = 0;  
  277.  
  278.       #if defined (PULLDOWN)
  279.         do
  280.         {
  281.           #if (OutD0 == 0)
  282.             KeyOutPort &= 0b11110000;
  283.             KeyOutPort |= (1 << columna);
  284.           #elif (OutD0 == 4)
  285.             KeyOutPort &= 0b00001111;
  286.             KeyOutPort |= (1 << (columna + 4));
  287.           #endif
  288.           #if (InD0 == 0)
  289.             key = PORTB & 0x0F;
  290.           #elif (InD0 == 4)
  291.             key = PORTB & 0xF0;
  292.             key = key >> 4;
  293.           #endif
  294.           columna++;
  295.         }
  296.         while ((key == 0) && (columna < 4));
  297.         if (key == 1) fila = 0;
  298.         else
  299.           if (key == 2) fila = 1;
  300.           else
  301.             if (key == 4) fila = 2;
  302.             else
  303.               if (key == 8) fila = 3;
  304.         #if (OutD0 == 0)
  305.           KeyOutPort |= 0b00001111;
  306.         #elif (OutD0 == 4)
  307.           KeyOutPort |= 0b11110000;
  308.         #endif
  309.         if (key != 0) return AsciiKey[fila][columna - 1];
  310.  
  311.      #elif defined (PULLUP)
  312.         do
  313.         {
  314.           #if (OutD0 == 0)
  315.             KeyOutPort |= 0b00001111;
  316.             KeyOutPort &= ~(1 << columna);
  317.           #elif (OutD0 == 4)
  318.             KeyOutPort |= 0b11110000;
  319.             KeyOutPort &= ~(1 << (columna + 4));
  320.           #endif  
  321.           #if (InD0 == 0)
  322.             key = PORTB & 0x0F;
  323.           #elif (InD0 == 4)
  324.             key = PORTB & 0xF0;
  325.             key = key >> 4;
  326.           #endif
  327.           columna++;
  328.         }
  329.         while ((key == 0x0F) && (columna < 4));
  330.         if (key == 0b00001110) fila = 0;
  331.         else
  332.           if (key == 0b00001101) fila = 1;
  333.           else
  334.             if (key == 0b00001011) fila = 2;
  335.             else
  336.               if (key == 0b00000111) fila = 3;
  337.         #if (OutD0 == 0)
  338.           KeyOutPort &= 0b11110000;
  339.         #elif (OutD0 == 4)
  340.           KeyOutPort &= 0b00001111;
  341.         #endif
  342.         if (key != 0x0F) return AsciiKey[fila][columna - 1];
  343.       #endif
  344.       return 0;
  345.     }
  346.  
  347.   #elif defined (OTRO)
  348.     const unsigned char AsciiKey [4][4] = {'1','2','3','A','4','5','6','B','7','8','9','C','*','0','#','D'};
  349.  
  350.     unsigned char GetKey (void)
  351.     {    
  352.       unsigned char key;
  353.       unsigned char fila = 0;
  354.       unsigned char columna = 0;  
  355.  
  356.       #if defined (PULLDOWN)
  357.         do
  358.         {
  359.           #if (OutD0 == 0)
  360.             KeyOutPort &= 0b11110000;
  361.             KeyOutPort |= (1 << columna);
  362.           #elif (OutD0 == 4)
  363.             KeyOutPort &= 0b00001111;
  364.             KeyOutPort |= (1 << (columna + 4));
  365.           #endif
  366.           #if (InD0 == 0)
  367.             key = PORTB & 0x0F;
  368.           #elif (InD0 == 4)
  369.             key = PORTB & 0xF0;
  370.             key = key >> 4;
  371.           #endif
  372.           columna++;
  373.         }
  374.         while ((key == 0) && (columna < 4));
  375.         if (key == 1) fila = 0;
  376.         else
  377.           if (key == 2) fila = 1;
  378.           else
  379.             if (key == 4) fila = 2;
  380.             else
  381.               if (key == 8) fila = 3;
  382.         #if (OutD0 == 0)
  383.           KeyOutPort |= 0b00001111;
  384.         #elif (OutD0 == 4)
  385.           KeyOutPort |= 0b11110000;
  386.         #endif
  387.         if (key != 0) return AsciiKey[fila][columna - 1];
  388.  
  389.      #elif defined (PULLUP)
  390.         do
  391.         {
  392.           #if (OutD0 == 0)
  393.             KeyOutPort |= 0b00001111;
  394.             KeyOutPort &= ~(1 << columna);
  395.           #elif (OutD0 == 4)
  396.             KeyOutPort |= 0b11110000;
  397.             KeyOutPort &= ~(1 << (columna + 4));
  398.           #endif  
  399.           #if (InD0 == 0)
  400.             key = PORTB & 0x0F;
  401.           #elif (InD0 == 4)
  402.             key = PORTB & 0xF0;
  403.             key = key >> 4;
  404.           #endif
  405.           columna++;
  406.         }
  407.         while ((key == 0x0F) && (columna < 4));
  408.         if (key == 0b00001110) fila = 0;
  409.         else
  410.           if (key == 0b00001101) fila = 1;
  411.           else
  412.             if (key == 0b00001011) fila = 2;
  413.             else
  414.               if (key == 0b00000111) fila = 3;
  415.         #if (OutD0 == 0)
  416.           KeyOutPort &= 0b11110000;
  417.         #elif (OutD0 == 4)
  418.           KeyOutPort &= 0b00001111;
  419.         #endif
  420.         if (key != 0x0F) return AsciiKey[fila][columna - 1];
  421.       #endif
  422.       return 0;
  423.     }
  424.   #endif
  425. #else
  426.   #error Faltan definir parametros
  427. #endif
Título: Re: Subo libreria para teclados en HiTech
Publicado por: XAVICOROSS en 22 de Noviembre de 2010, 01:52:06
Gracias, las probare enseguida, es un excelente aporte...
Título: Re: Subo libreria para teclados en HiTech
Publicado por: micro_pepe en 07 de Mayo de 2011, 17:27:46
He probado esta librería en real con un cristal de 8MHz, y funciona perfectamente. Ahora con un cristal de 20MHz, no me funciona, lo he solucionado poniendo unos retardos de 2uS.

La libreria queda así:

Código: [Seleccionar]
/**************************************************************************
*        Librerira para manejar teclados 3x4 y 4x4 para Hitech            *
***************************************************************************
 
***************************************************************************
* El puerto de entrada puede estar con resistencias de Pull-up o con      *
* resistencias de Pull-Down.                                              *
***************************************************************************
 
***************************************************************************
*                                                                         *
* Antes de incluir este archivo en nuestro programa hay que definir       *
* algunos parametros. Estos son                                           *
*                                                                         *
* KeyOutPort       (el puerto que se utilizara como salida)               *
* KeyInPort        (el puerto que se utilizara como entrada)              *
* OutD0            (el primer bit de salida)                              *
* InD0             (el primer bit de entrada)                             *
*                                                                         *
* Segun el teclado a utilizar hay que definir PHONE HEXA u OTRO           *
* Si el tipo de teclado es PHONE OutD0 puede tomar los siguientes valores *
* 0, 1, 4 o 5. InD0 puede ser 0 o 4                                       *
*                                                                         *
* Para teclados del tipo HEXA u OTRO OutD0 e InD0 solo pueden ser 0 o 4   *
*                                                                         *
* Si se van utilizar resistencias de Pull-up hay que definir PULLUP       *
* Si se van utilizar resistencias de Pull-Down hay que definir PULLDOWN   *
*                                                                         *
***************************************************************************
 
***************************************************************************
* La unica funcion disponible es GetKey y devuelve el codigo ASCII de la  *
* tecla precionada                                                        *
***************************************************************************
 
***************************************************************************
*                      Disposicion de teclados                            *
*                                                                         *
* Como los unicos bits definidos son OutD0 e InD0, el resto de los bits   *
* se usan a partir del D0. Es decir, si definimos OutD0 1 quiere decir    *
* que OutD0 tiene que estar conectado al bit 1 del puerto elegido, de     *
* esta forma OutD1 tiene que ir conectado al bit 2 y OutD2 al bit 3       *
* El mismo razonamiento se utiliza para los bits de entrada               *
***************************************************************************
 
 
***************************************************************************
*                           PHONE                                         *
*                                                                         *
*                    OutD0   OutD1   OutD2                                *
*                      |       |       |                                  *
*                     ---     ---     ---                                 *
*            InD0 ---| 1 |---| 2 |---| 3 |                                *
*                     ---     ---     ---                                 *
*                      |       |       |                                  *
*                     ---     ---     ---                                 *
*            InD1 ---| 4 |---| 5 |---| 6 |                                *
*                     ---     ---     ---                                 *
*                      |       |       |                                  *
*                     ---     ---     ---                                 *
*            InD2 ---| 7 |---| 8 |---| 9 |                                *
*                     ---     ---     ---                                 *
*                      |       |       |                                  *
*                     ---     ---     ---                                 *
*            InD3 ---| * |---| 0 |---| # |                                *
*                     ---     ---     ---                                 *
*                                                                         *
***************************************************************************
 
***************************************************************************
*                               HEXA                                      *
*                                                                         *
*                    OutD0   OutD1   OutD2   OutD3                        *
*                      |       |       |       |                          *
*                     ---     ---     ---     ---                         *
*            InD0 ---| 0 |---| 1 |---| 2 |---| 3 |                        *
*                     ---     ---     ---     ---                         *
*                      |       |       |       |                          *
*                     ---     ---     ---     ---                         *
*            InD1 ---| 4 |---| 5 |---| 6 |---| 7 |                        *
*                     ---     ---     ---     ---                         *
*                      |       |       |       |                          *
*                     ---     ---     ---     ---                         *
*            InD2 ---| 8 |---| 9 |---| A |---| B |                        *
*                     ---     ---     ---     ---                         *
*                      |       |       |       |                          *
*                     ---     ---     ---     ---                         *
*            InD3 ---| C |---| D |---| E |---| F |                        *
*                     ---     ---     ---     ---                         *
*                                                                         *
***************************************************************************
 
***************************************************************************
*                               OTRO                                      *
*                                                                         *
*                    OutD0   OutD1   OutD2   OutD3                        *
*                      |       |       |       |                          *
*                     ---     ---     ---     ---                         *
*            InD0 ---| 1 |---| 2 |---| 3 |---| A |                        *
*                     ---     ---     ---     ---                         *
*                      |       |       |       |                          *
*                     ---     ---     ---     ---                         *
*            InD1 ---| 4 |---| 5 |---| 6 |---| B |                        *
*                     ---     ---     ---     ---                         *
*                      |       |       |       |                          *
*                     ---     ---     ---     ---                         *
*            InD2 ---| 7 |---| 8 |---| 9 |---| C |                        *
*                     ---     ---     ---     ---                         *
*                      |       |       |       |                          *
*                     ---     ---     ---     ---                         *
*            InD3 ---| * |---| 0 |---| # |---| D |                        *
*                     ---     ---     ---     ---                         *
*                                                                         *
***************************************************************************
 
* Ejemplo de configuración y utilización
 
 Se usa un teclado tipo PHONE, se leen los datos por el nibble alto del puerto B
 con resistencias de pull-down
 y para la salida hacia el teclado se usa parte del nibble bajo del puerto A
 
 En un PIC 16F876A
 
 
 #define PHONE
 #define PULLDOWN
 #define KeyOutPort PORTA
 #define KeyInPort  PORTB
 #define OutD0      0
 #define InD0       4
 
 #include "Teclados.c"
 
 
 void main (void)
 {
   unsigned char Tecla_pulsada;
 
   CMCON = 7;          // desactivo los comparadores
   ADON = 0;           // apago el conversor AD
   ADCON1 =  0x07;     // entradas digitales
 
   TRISB = 0xF0;       // el nibble alto como entrada
   TRISA = 0;          // puerto como salida
   TRISC = 0;          // puerto C como salida
   PORTC = 0;
   PORTA = 0x07;       // salidas del puerto A en "1"
 
   while (1)
   {
     if ((PORTB & 0xF0) != 0) //si hay alguna tecla presionada
     {
       // alguna rutina de espera de unos 10ms para Antirebote
       if ((PORTB & 0xF0) != 0) si sigue presionada
       {
         Tecla_pulsada = GetKey();  //leeo el teclado
         if (Tecla_pulsada != 0) PORTC = Tecla_pulsada; // muestro en el puerto C el valor leido
       }
     }
   }
 }
 
 
 
*/
 
#if (defined (KeyOutPort) && defined (KeyInPort) && defined (OutD0) && defined (InD0)) \
    && (defined (PHONE) || defined (HEXA) || defined (OTRO)) && \
    (defined (PULLUP) || defined (PULLDOWN))
 
  #if defined (PHONE)
    const unsigned char AsciiKey [4][3] = {'1','2','3','4','5','6','7','8','9','*','0','#'};
 
    unsigned char GetKey (void)
    {     
      unsigned char key;
      unsigned char fila = 0;
      unsigned char columna = 0;   
 
      #if defined (PULLDOWN)
        do
        {
          #if (OutD0 == 0)
            KeyOutPort &= 0b11111000;
            KeyOutPort |= (1 << columna);
          #elif (OutD0 == 1)
            KeyOutPort &= 0b11110001;
            KeyOutPort |= (1 << (columna + 1));
          #elif (OutD0 == 4)
            KeyOutPort &= 0b10001111;
            KeyOutPort |= (1 << (columna + 4));
          #elif (OutD0 == 5)
            KeyOutPort &= 0b00011111;
            KeyOutPort |= (1 << (columna + 5));
          #endif
  DelayUs(2);
          #if (InD0 == 0)
            key = PORTB & 0x0F;
          #elif (InD0 == 4)
            key = PORTB & 0xF0;
            key = key >> 4;
          #endif
  DelayUs(2);
          columna++;
        }
        while ((key == 0) && (columna < 3));
        if (key == 1) fila = 0;
        else
          if (key == 2) fila = 1;
          else
            if (key == 4) fila = 2;
            else
              if (key == 8) fila = 3;
        #if (OutD0 == 0)
          KeyOutPort |= 0b00000111;
        #elif (OutD0 == 1)
          KeyOutPort |= 0b00001110;
        #elif (OutD0 == 4)
          KeyOutPort |= 0b01110000;
        #elif (OutD0 == 5)
          KeyOutPort |= 0b11100000;
        #endif
DelayUs(2);
        if (key != 0) return AsciiKey[fila][columna - 1];
 
     #elif defined (PULLUP)
        do
        {
          #if (OutD0 == 0)
            KeyOutPort |= 0b00000111;
            KeyOutPort &= ~(1 << columna);
          #elif (OutD0 == 1)
            KeyOutPort |= 0b00001110;
            KeyOutPort &= ~(1 << (columna + 1));
          #elif (OutD0 == 4)
            KeyOutPort |= 0b01110000;
            KeyOutPort &= ~(1 << (columna + 4));
          #elif (OutD0 == 5)
            KeyOutPort |= 0b11100000;
            KeyOutPort &= ~(1 << (columna + 5));
          #endif 
  DelayUs(2);
          #if (InD0 == 0)
            key = PORTB & 0x0F;
          #elif (InD0 == 4)
            key = PORTB & 0xF0;
            key = key >> 4;
          #endif
  DelayUs(2);
          columna++;
        }
        while ((key == 0x0F) && (columna < 3));
        if (key == 0b00001110) fila = 0;
        else
          if (key == 0b00001101) fila = 1;
          else
            if (key == 0b00001011) fila = 2;
            else
              if (key == 0b00000111) fila = 3;
        #if (OutD0 == 0)
          KeyOutPort &= 0b11111000;
        #elif (OutD0 == 1)
          KeyOutPort &= 0b11110001;
        #elif (OutD0 == 4)
          KeyOutPort &= 0b10001111;
        #elif (OutD0 == 5)
          KeyOutPort &= 0b00011111;
        #endif
DelayUs(2);
        if (key != 0x0F) return AsciiKey[fila][columna - 1];
      #endif
      return 0;
    }
 
  #elif defined (HEXA)
    const unsigned char AsciiKey [4][4] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
 
    unsigned char GetKey (void)
    {     
      unsigned char key;
      unsigned char fila = 0;
      unsigned char columna = 0;   
 
      #if defined (PULLDOWN)
        do
        {
          #if (OutD0 == 0)
            KeyOutPort &= 0b11110000;
            KeyOutPort |= (1 << columna);
          #elif (OutD0 == 4)
            KeyOutPort &= 0b00001111;
            KeyOutPort |= (1 << (columna + 4));
          #endif
  DelayUs(2);
          #if (InD0 == 0)
            key = PORTB & 0x0F;
          #elif (InD0 == 4)
            key = PORTB & 0xF0;
            key = key >> 4;
          #endif
  DelayUs(2);
          columna++;
        }
        while ((key == 0) && (columna < 4));
        if (key == 1) fila = 0;
        else
          if (key == 2) fila = 1;
          else
            if (key == 4) fila = 2;
            else
              if (key == 8) fila = 3;
        #if (OutD0 == 0)
          KeyOutPort |= 0b00001111;
        #elif (OutD0 == 4)
          KeyOutPort |= 0b11110000;
        #endif
DelayUs(2);
        if (key != 0) return AsciiKey[fila][columna - 1];
 
     #elif defined (PULLUP)
        do
        {
          #if (OutD0 == 0)
            KeyOutPort |= 0b00001111;
            KeyOutPort &= ~(1 << columna);
          #elif (OutD0 == 4)
            KeyOutPort |= 0b11110000;
            KeyOutPort &= ~(1 << (columna + 4));
          #endif
  DelayUs(2);
          #if (InD0 == 0)
            key = PORTB & 0x0F;
          #elif (InD0 == 4)
            key = PORTB & 0xF0;
            key = key >> 4;
          #endif
  DelayUs(2);
          columna++;
        }
        while ((key == 0x0F) && (columna < 4));
        if (key == 0b00001110) fila = 0;
        else
          if (key == 0b00001101) fila = 1;
          else
            if (key == 0b00001011) fila = 2;
            else
              if (key == 0b00000111) fila = 3;
        #if (OutD0 == 0)
          KeyOutPort &= 0b11110000;
        #elif (OutD0 == 4)
          KeyOutPort &= 0b00001111;
        #endif
DelayUs(2);
        if (key != 0x0F) return AsciiKey[fila][columna - 1];
      #endif
  DelayUs(2);
      return 0;
    }
 
  #elif defined (OTRO)
    const unsigned char AsciiKey [4][4] = {'1','2','3','A','4','5','6','B','7','8','9','C','*','0','#','D'};
 
    unsigned char GetKey (void)
    {     
      unsigned char key;
      unsigned char fila = 0;
      unsigned char columna = 0;   
 
      #if defined (PULLDOWN)
        do
        {
          #if (OutD0 == 0)
            KeyOutPort &= 0b11110000;
            KeyOutPort |= (1 << columna);
          #elif (OutD0 == 4)
            KeyOutPort &= 0b00001111;
            KeyOutPort |= (1 << (columna + 4));
          #endif
  DelayUs(2);
          #if (InD0 == 0)
            key = PORTB & 0x0F;
          #elif (InD0 == 4)
            key = PORTB & 0xF0;
            key = key >> 4;
          #endif
  DelayUs(2);
          columna++;
        }
        while ((key == 0) && (columna < 4));
        if (key == 1) fila = 0;
        else
          if (key == 2) fila = 1;
          else
            if (key == 4) fila = 2;
            else
              if (key == 8) fila = 3;
        #if (OutD0 == 0)
          KeyOutPort |= 0b00001111;
        #elif (OutD0 == 4)
          KeyOutPort |= 0b11110000;
        #endif
DelayUs(2);
        if (key != 0) return AsciiKey[fila][columna - 1];
 
     #elif defined (PULLUP)
        do
        {
          #if (OutD0 == 0)
            KeyOutPort |= 0b00001111;
            KeyOutPort &= ~(1 << columna);
          #elif (OutD0 == 4)
            KeyOutPort |= 0b11110000;
            KeyOutPort &= ~(1 << (columna + 4));
          #endif
  DelayUs(2); 
          #if (InD0 == 0)
            key = PORTB & 0x0F;
          #elif (InD0 == 4)
            key = PORTB & 0xF0;
            key = key >> 4;
          #endif
  DelayUs(2);
          columna++;
        }
        while ((key == 0x0F) && (columna < 4));
        if (key == 0b00001110) fila = 0;
        else
          if (key == 0b00001101) fila = 1;
          else
            if (key == 0b00001011) fila = 2;
            else
              if (key == 0b00000111) fila = 3;
        #if (OutD0 == 0)
          KeyOutPort &= 0b11110000;
        #elif (OutD0 == 4)
          KeyOutPort &= 0b00001111;
        #endif
DelayUs(2);
        if (key != 0x0F) return AsciiKey[fila][columna - 1];
      #endif
  DelayUs(2);
      return 0;
    }
  #endif
#else
  #error Faltan definir parametros
#endif

Solo lo he probado con un teclado de 12 teclas.

Saludos.