Problemas con teclado matricial kbd.c

Hola, buenas tardes, este es mi primer tema, así que espero que todo salga bien, bueno, primero les platico que nos dejaron hacer un programa en clase con una PIC16F877A para que simulara un piano, es decir, cada tecla del teclado matricial fuera un tono, con unas más para melodías definidas, y que se imprimiera en un lcd. Relativamente lo tengo listo, es decir, hace todo lo que pide, pero no logro hacer que funcione para que mientras mantengo presionada la tecla suene, y no solo después de presionar y soltar, alguno me podría ayudar, aquí van los códigos...

Mi código principal al que llamo piano.c
Código:
#include <16F877A.h>                         //Dispositivo
#fuses XT, NOWDT, NOPUT, NOBROWNOUT, NOLVP   //Fusibles
#use delay(clock=4000000)                    //Reloj
#include "2lcd.c"
#define use_portb_kbd TRUE
#include "2kbd.c"
#include "2tones.c"
#include "fun_piano.h"



void main(){
   lcd_init();
   port_b_pullups(TRUE);
   int cont=1;
   char c;
   while(TRUE){
      c = kbd_getc();
      if(c!=0){
         switch(c){
            case '0':
               printf(lcd_putc,"DO ");
               generate_tone(C_NOTE[0],1000);
               cont = conteo_piano(cont);
               break;
            case '1':
               printf(lcd_putc,"DO# ");
               generate_tone(Cb_NOTE[0],1000);
               cont = conteo_piano(cont);
               break;
            case '2':
               printf(lcd_putc,"RE ");
               generate_tone(D_NOTE[0],1000);
               cont = conteo_piano(cont);
               break;
            case '3':
               printf(lcd_putc,"RE# ");
               generate_tone(Db_NOTE[0],1000);
               cont = conteo_piano(cont);
               break;
            case '4':
               printf(lcd_putc,"MI ");
               generate_tone(E_NOTE[0],1000);
               cont = conteo_piano(cont);
               break;
            case '5':
               printf(lcd_putc,"MI# ");
               generate_tone(Eb_NOTE[0],1000);
               cont = conteo_piano(cont);
               break;
            case '6':
               printf(lcd_putc,"FA ");
               generate_tone(F_NOTE[0],1000);
               cont = conteo_piano(cont);
               break;
            case '7':
               printf(lcd_putc,"SOL ");
               generate_tone(G_NOTE[0],1000);
               cont = conteo_piano(cont);
               break;
            case '8':
               printf(lcd_putc,"SOL# ");
               generate_tone(Gb_NOTE[0],1000);
               cont = conteo_piano(cont);
               break;
            case '9':
               printf(lcd_putc,"LA ");
               generate_tone(A_NOTE[0],1000);
               cont = conteo_piano(cont);
               break;
            case '/':
               printf(lcd_putc,"LA# ");
               generate_tone(Ab_NOTE[0],1000);
               cont = conteo_piano(cont);
               break;
            case '*':
               printf(lcd_putc,"SI ");
               generate_tone(B_NOTE[0],1000);
               cont = conteo_piano(cont);
               break;
            case '-':
               printf(lcd_putc,"SI# ");
               generate_tone(Bb_NOTE[0],1000);
               cont = conteo_piano(cont);
               break;
            case 'C':
               printf(lcd_putc,"\f");
               cont=0;
               break;
            case '+':
               melodias(3);
               cont=0; 
               break;
            case '=':
               melodias(4);
               cont=0;
               break;
         }
      }
   }
}

Mi libreria del teclado kbd
Código:
////                             KBD.C                                 ////
////                  Generic keypad scan driver                       ////
////                                                                   ////
////  kbd_init()   Must be called before any other function.           ////
////                                                                   ////
////  c = kbd_getc(c)  Will return a key value if pressed or /0 if not ////
////                   This function should be called frequently so as ////
////                   not to miss a key press.                        ////
////                                                                   ////
///////////////////////////////////////////////////////////////////////////
////        (C) Copyright 1996,2003 Custom Computer Services           ////
//// This source code may only be used by licensed users of the CCS C  ////
//// compiler.  This source code may only be distributed to other      ////
//// licensed users of the CCS C compiler.  No other use, reproduction ////
//// or distribution is permitted without written permission.          ////
//// Derivative programs created using this software in object code    ////
//// form are not restricted in any way.                               ////
///////////////////////////////////////////////////////////////////////////

////////////////// The following defines the keypad layout on port D

// Un-comment the following define to use port B
// #define use_portb_kbd TRUE

// Make sure the port used has pull-up resistors (or the LCD) on
// the column pins

#if defined use_portb_kbd
   #byte kbd = getenv("SFR:PORTB")
#else
   #byte kbd = getenv("SFR:PORTD")
#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

//Keypad connection:   (for example column 0 is B2)
//                Bx:

#ifdef blue_keypad  ///////////////////////////////////// For the blue keypad
#define COL0 (1 << 4)
#define COL1 (1 << 5)
#define COL2 (1 << 6)
#define COL3 (1 << 7)

#define ROW0 (1 << 0)
#define ROW1 (1 << 1)
#define ROW2 (1 << 2)
#define ROW3 (1 << 3)

#else ////////////////////////////////////////////////// For the black keypad
#define COL0 (1 << 4)
#define COL1 (1 << 5)
#define COL2 (1 << 6)
#define COL3 (1 << 7)

#define ROW0 (1 << 0)
#define ROW1 (1 << 1)
#define ROW2 (1 << 2)
#define ROW3 (1 << 3)

#endif

#define ALL_ROWS (ROW0|ROW1|ROW2|ROW3)
#define ALL_PINS (ALL_ROWS|COL0|COL1|COL2|COL3)

// Keypad layout:
char const KEYS[4][4] = {{'7','8','9','/'},
                         {'4','5','6','*'},
                         {'1','2','3','-'},
                         {'C','0','=','+'}};

#define KBD_DEBOUNCE_FACTOR 33    // Set this number to apx n/333 where
                                  // n is the number of times you expect
                                  // to call kbd_getc each second


void kbd_init() {
}

char kbd_getc( ) {
   static BYTE kbd_call_count;
   static int1 kbd_down;
   static char last_key;
   static BYTE col;

   BYTE kchar;
   BYTE row;

   kchar='\0';
   if(++kbd_call_count>KBD_DEBOUNCE_FACTOR) {
       switch (col) {
         case 0   : set_tris_kbd(ALL_PINS&~COL0);
                    kbd=~COL0&ALL_PINS;
                    break;
         case 1   : set_tris_kbd(ALL_PINS&~COL1);
                    kbd=~COL1&ALL_PINS;
                    break;
         case 2   : set_tris_kbd(ALL_PINS&~COL2);
                    kbd=~COL2&ALL_PINS;
                    break;
         case 3   : set_tris_kbd(ALL_PINS&~COL3);
                    kbd=~COL3&ALL_PINS;
                    break;
       }

       if(kbd_down) {
         if((kbd & (ALL_ROWS))==(ALL_ROWS)) {
           kbd_down=FALSE;
           kchar=last_key;
           last_key='\0';
         }
       } else {
          if((kbd & (ALL_ROWS))!=(ALL_ROWS)) {
             if((kbd & ROW0)==0)
               row=0;
             else if((kbd & ROW1)==0)
               row=1;
             else if((kbd & ROW2)==0)
               row=2;
             else if((kbd & ROW3)==0)
               row=3;
             last_key =KEYS[row][col];
             kbd_down = TRUE;
          } else {
             ++col;
             if(col==4)
               col=0;
          }
       }
      kbd_call_count=0;
   }
  set_tris_kbd(ALL_PINS);
  return(kchar);
}

Les dejo también el proyecto completo para descargar, tengo unas melodías que tal vez a alguien más le puedan servir en una cabecera y está el diseño para Proteus, espero sus respuestas y comentarios, muchas gracias.
 

Adjuntos

  • Piano.zip
    103.8 KB · Visitas: 9
lo que hace la libreria del keypad cuando esta conectada al puerto b activa las interrupciones por cambio de flanco,si no hay cambio de pulso no lo reconoce; lo que debes hacer es cambiar el keypad al puerto d e ponerle resistencias pull-up los que trae el puerto b ademas reduce tus delays para que testee lo mas rapido el dato que se manda a traves del keypad
 
Arriba