This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

midi interface 8051 uart problem

hi, i am trying to make a midi interface for my old yamaha pss-25 which has 5x10 key matrix, every things works perfectly except this one. after turning on the system when i pressed any key uart send the data like this [0x90 0x90 0xXX 0xXX], which should be [0x90 0xXX 0xXX]. (XX=00-FF). frustration in this problem is only for first key pressed, after that the data string become normal like above mentioned string.

This is my code:

/* Main.c file generated by New Project wizard
 *
 * Created:   Mon Apr 24 2017
 * Processor: AT89C2051
 * Compiler:  Keil for 8051
 */

#include <reg51.h>

#define NUM_ROWS 5
#define NUM_COLS 10

#define NOTE_ON_CMD 0x90
#define NOTE_OFF_CMD 0x80
#define NOTE_VELOCITY 127

// Row input pins.
sbit row1 = P1^0;
sbit row2 = P1^1;
sbit row3 = P1^2;
sbit row4 = P1^3;
sbit row5 = P1^4;
sbit row6 = P1^5;

// 74HC595 pins.
sbit sdata = P3^5;
sbit latch = P3^4;
sbit clock = P3^7;

// Variables
//unsigned char

// bitmasks for scanning columns.
unsigned char code bits[] ={0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF, 0x7F};
unsigned char keyToMidiMap[NUM_ROWS][NUM_COLS];
unsigned char keyPressed[NUM_ROWS][NUM_COLS];

// Functions


void delay(unsigned char s)
{
char p;
for(p=0;p<s;p++);
}

void init_serial()// Initialize serial port
   {
   TMOD=0x21;   // Timer1 @ Mode 2 (8-bit auto relode)
   SCON=0x50;   // Serial mode=1, 8-Bit data, 1Stop bit, 1 Start bit, Receiving 0n
   IE=0x95;     // Enables Serial Interrupt
   IT0=1;       // the interrupt at INT0 would be evoked by a falling edge signal (high to low transition).
   IT1=1;       // the interrupt at INT1 would be evoked by a falling edge signal (high to low transition).
   IE=0x90;     // Enables Serial Interrupt
   TH1=0xFF;    // 31250 baud rate MIDI standerd @ 12MHz crystal.
   TR1=1;       // Start timer
   }

void transmit_data(unsigned int dat)// Function to transmitdata through serial port
   {
   SBUF=dat;    //Store data in SBUF
   while(TI==0); //Wait till datatransmits
   TI=0;
   }

void noteOn(unsigned char row, unsigned char col)
{
   transmit_data(NOTE_ON_CMD);
   transmit_data(keyToMidiMap[row][col]);
   transmit_data(NOTE_VELOCITY);
}

void noteOff(unsigned char row,unsigned  char col)
{
   transmit_data(NOTE_OFF_CMD);
   transmit_data(keyToMidiMap[row][col]);
   transmit_data(NOTE_VELOCITY);
}

void shiftOut(unsigned char val)
{
   unsigned char i;
   for(i=0;i<8;i++)
   {
      sdata=!!(val & (1 << (7 - i)));
      clock=1;
      clock=0;
   }
}


void scanColumn(unsigned char colNum)
{
   latch=0;
   if(0<=colNum&&colNum<=7)
   {
      shiftOut(0xFF);
      shiftOut(bits[colNum]);
   }
   else
   {
      shiftOut(bits[colNum-8]);
      shiftOut(0xFF);
   }
   latch=1;
}


void main(void)
{
  unsigned char note = 36;
  unsigned char colCtr;
  unsigned char rowCtr;
  unsigned char rowValue[NUM_ROWS];     //get row values at this column
   sdata=0;
   latch=0;
   clock=0;
   P1=0xff;

  for(colCtr = 0; colCtr < NUM_COLS; ++colCtr)
  {
    for(rowCtr = 0; rowCtr < NUM_ROWS; ++rowCtr)
    {
      keyPressed[rowCtr][colCtr] = 0x00;
      keyToMidiMap[rowCtr][colCtr] = note;
      note++;
    }
  }
  init_serial();
  while(1)
  {
   for (colCtr = 0; colCtr < NUM_COLS; ++colCtr)
    {
    scanColumn(colCtr); //scan next column
    rowValue[0] = !row1;
    rowValue[1] = !row2;
    rowValue[2] = !row3;
    rowValue[3] = !row4;
    rowValue[4] = !row5;
    rowValue[5] = !row6;

    // process keys pressed
    for(rowCtr=0; rowCtr<NUM_ROWS; ++rowCtr)
    {
      if(rowValue[rowCtr]!=0 && keyPressed[rowCtr][colCtr]==0x00)
      {
        noteOn(rowCtr,colCtr);
        keyPressed[rowCtr][colCtr] = 0xFF;
      }
    }

    // process keys released
    for(rowCtr=0; rowCtr<NUM_ROWS; ++rowCtr)
    {
      if(rowValue[rowCtr]==0 && keyPressed[rowCtr][colCtr]==0xFF)
      {
        noteOff(rowCtr,colCtr);
        keyPressed[rowCtr][colCtr] = 0x00;
      }
    }
  }
}
}