Autor Tema: Problemas leiendo midi con USART y c30, ayuda!!  (Leído 3183 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado eusebioelmelenas

  • PIC10
  • *
  • Mensajes: 4
Problemas leiendo midi con USART y c30, ayuda!!
« en: 23 de Marzo de 2009, 09:39:35 »
Hola buenas! a ver si me podeis hechar un cable....
en un principio el programa debe leer midi y tiene que poder guardarlo. La problemática con la que me he encontrado es que mi señal midi ( un teclado ) cada "x" tiempo baja la señal, como si fuera una bit de start, pero evidentemente después no envia esos 3 bytes de midi... porque tampoco he tocado ninguna tecla. He hecho un montón de pruevas pero no encuentro como salir de esta problemática....utilzo la libreria de c30 para programarlo.
Este mismo programa cambiando algunas cosillas lo he utilizado para rs-232 y no he tenido ningún problema. A ver si veis algun tipo de error.. .algo que se me escapa y no lo veo.....
A la hora de leer el midi recibido en un principio sino me equivoco y si lo hago espero que me hecheis un cable, leo  el Buf[0], Buf[1] i Buf[2] entendiendo que en cada char que compone esta lista.. es cada byte recibido. No se si una posible solución seria cambiar la variable char Buf [80], por otro tipo.. pero creo que al ser bytes de 8 bits no tiene porque haber diferencia.. ya que este mismo lo he utilizado para Rs-232 y no  tube problema. Espero con ansias que me contesteis...


pd: El protocolo MIDI se transmite como bytes asíncronos a 31250 bits por segundo.  y lanza 3 bytes


// Fitxers includes de microprocontrolador DSPIC i operadors Matemàtics
#include "p30f4012.h"
#include "math.h"
#include "pwm.h"
#include "uart.h"
#include "ports.h"
#include "libpic30.h"
#include "stdio.h"
 

// ++++++++++++++++++++++++++++++++++ Definicions ++++++++++++++++++++++++++++++++++++++
char Buf[80];
char * Receiveddata = Buf;

int f, MIDI, config;


void tiempo(void);

//void configUSARTmidi();
//void menuinicial ();

//+++++++++++++++++++++++++++++ Programació bits de control DSPIC++++++++++++++++++++++++++++++++++++++++++++++
_FOSC(CSW_FSCM_OFF & XT_PLL8);  // clock extern x PLL x 8 = 10e+6*8/4 = 20 MHz
_FWDT(WDT_OFF);                 // Borra Watch-Dog Timer.
_FBORPOR(MCLR_EN & PWRT_OFF);   // Habilita pin MCLR reset i apaga power-up timers.
_FGS(CODE_PROT_OFF);            // Disabilita protecció de codi



/* ++++++++++++++++++++++++++++++++++Interrupció de transmisió++++++++++++++++++++++++++++++++++ */
void __attribute__((__interrupt__, no_auto_psv)) _U1TXInterrupt(void)
{
IFS0bits.U1TXIF = 0;
}


/*++++++++++++++++++++++++++++++++++++ Interrupció de recepció++++++++++++++++++++++++++++++++++++++ */
void __attribute__((__interrupt__, no_auto_psv)) _U1RXInterrupt(void)
{

IFS0bits.U1RXIF = 0; //baixa la bandera d'aquesta interrupció

      while( DataRdyUART1())  // condició a 1, mentres está rebent info
      {

      ( *( Receiveddata)++) = ReadUART1(); // d'aquesta manera em guarda el 3 bytes junts
      
       
      }
   

}


/

// +++++++++++++++++++++++++++++++++++++configuració modul UART per a MIDI+++++++++++++++++++++++++++++++
/*void configUSARTmidi() // cridarla en el main... o l'nterrupció
{
 unsigned int baudios, U1MODEvalue, U1STAvalue;
 ConfigIntUART1(UART_RX_INT_EN //RECEIVE INTERRUPT DISABLE
            & UART_RX_INT_PR2 //RECEIVE INTERRUPT PRIORITY
            & UART_TX_INT_EN // TRANSMIT INTERRUPT DISABLE
            & UART_TX_INT_PR6); // TRANSMIT INTERRUPT PRORITY
 baudios = 41; //AL REGISTRO UBRG calculado por mi ;
 U1MODEvalue = UART_EN  // UART ENABLE
          & UART_IDLE_STOP // MODO DE ESPERA
          & UART_RX_TX // COMUNICACIO AMB RX I TX
          & UART_DIS_WAKE // WAKE-UP  ON START
          & UART_DIS_LOOPBACK // LOOPBACK MODE.. originalemente en DIS
          & UART_DIS_ABAUD // INPUT TO CAPTURE MODULE
             & UART_NO_PAR_8BIT // PARIY AND DATA BITS SELECT
          & UART_1STOPBIT; //NUMBER O STOP BITS
 U1STAvalue = UART_INT_TX_BUF_EMPTY // TRANSMISION MODE INTERRUPT SELECT
         & UART_TX_PIN_NORMAL // TRANSMIT BREAK BIT
         & UART_TX_ENABLE // TRANSMIT ENABLE
         & UART_INT_RX_CHAR // RECEIVE INTERRUPT MODE SELECT
         & UART_ADR_DETECT_DIS //ADDRESS DETECT
         & UART_RX_OVERRUN_CLEAR; // OVERRUN BEAT CLEAR

 OpenUART1(U1MODEvalue, U1STAvalue, baudios);
} */






//PROGRAMA PRINCIPAL
int main(void)
{


// ++++++++++++++++++++++++++ PARA LA UART ++++++++++++++++++++++++++++++++++++++++++++++++++

ConfigIntUART1(UART_RX_INT_EN // RECEIVE INTERRUPT ENABLE
         & UART_RX_INT_PR6 // RECEIVE INTERRUPT PRIORITY
         & UART_TX_INT_EN // TRANSMIT INTERRUPT ENABLE
         & UART_TX_INT_PR2); // TRANSMIT INTERRUPT PRIORITY

 configUSART1midi();  //


//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
   TRISBbits.TRISB0 =0;
   TRISBbits.TRISB1 =0;
   TRISBbits.TRISB2 =0;
   TRISBbits.TRISB3 =0;
   TRISBbits.TRISB4 =0;
   TRISBbits.TRISB5 =0;
   
// INICIALITZIÓ DE VARIABLES
   
 

   
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++





      PORTBbits.RB0= 0;
   PORTBbits.RB1= 0;   
   PORTBbits.RB2= 0;
   PORTBbits.RB3= 0;
   PORTBbits.RB4= 0;
   PORTBbits.RB5= 0;      
      

   
      

   
   while (f!=1){}  // espera fins que reb algo
   f=0;  //flag de interrupció de rebuda
      

      

while(1)
{
      
........
................
........................
...............................
....................................
   
 

}   // BUCLE REPETITIU
}   // FI MAIN



Desconectado alogic.on

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 772
Re: Problemas leiendo midi con USART y c30, ayuda!!
« Respuesta #1 en: 28 de Marzo de 2009, 19:00:49 »
Citar
La problemática con la que me he encontrado es que mi señal midi ( un teclado ) cada "x" tiempo baja la señal, como si fuera una bit de start, pero evidentemente después no envia esos 3 bytes de midi... porque tampoco he tocado ninguna tecla.
hola, comprueba a ver que dato es el que envia tu teclado cada X tiempo, por si es la señal de active sensing
Mensaje enviado cada tercio de segundo para verificar que el instrumento está conectado al sistema y respondiendo.
byte: bin 1111 1110, dec 254, hex FE
norma midi 1.0
para monitorear midi lo puedes hacer con midiox
siento no poder ayudarte con la programacion, lo unico que se es trastear con asm  :(

un saludo

Desconectado eusebioelmelenas

  • PIC10
  • *
  • Mensajes: 4
Re: Problemas leiendo midi con USART y c30, ayuda!!
« Respuesta #2 en: 31 de Marzo de 2009, 19:11:51 »
Gracias por la respuesta, mañana mismo lo comprobaré a ver si saco algo de ahí...

Ya comentaré a ver si saco algo en claro...

En la programación se pueden ver errores tipo que no corresponden los nombres de las funciones... pero planteado un poco algoritmicamente.... en realidad me compila y esas cosas... pero no se si el error es de configuracion de la uart cosas por el estilo.

Saludos!

Desconectado eusebioelmelenas

  • PIC10
  • *
  • Mensajes: 4
Re: Problemas leiendo midi con USART y c30, ayuda!!
« Respuesta #3 en: 02 de Abril de 2009, 07:42:19 »
Pues no he tenido suerte hasta el momento... aqui dejo el programa que compila sin errores.. pero no hace lo q me gustaria que hiciese...

// Fitxers includes de microprocontrolador DSPIC i operadors Matemàtics
#include "p30f4012.h"
#include "math.h"
#include "pwm.h"
#include "uart.h"
#include "ports.h"
#include "libpic30.h"
#include "stdio.h"
#include "timer.h"



// ++++++++++++++++++++++++++++++++++ Definicions ++++++++++++++++++++++++++++++++++++++
int Buf[80];
int midi[80];

int * Receiveddata = Buf;

int f, MIDI, config, ignore, limite;
unsigned int timer_value, valor_a_comparar;

void tiempo(void);

void configUSARTmidi();


//+++++++++++++++++++++++++++++ Programació bits de control DSPIC++++++++++++++++++++++++++++++++++++++++++++++
_FOSC(CSW_FSCM_OFF & XT_PLL8);  // clock extern x PLL x 8 = 10e+6*8/4 = 20 MHz
_FWDT(WDT_OFF);                 // Borra Watch-Dog Timer.
_FBORPOR(MCLR_EN & PWRT_OFF);   // Habilita pin MCLR reset i apaga power-up timers.
_FGS(CODE_PROT_OFF);            // Disabilita protecció de codi

/* ++++++++++++++++++++++++++++++++++Interrupció del Timer 1 ++++++++++++++++++++++++++++++++++ */
void __attribute__((__interrupt__, no_auto_psv)) _T1Interrupt(void)
{
limite = 1;
IFS0bits.T1IF = 0; // baixa la bandera de la interrupció

}

/* ++++++++++++++++++++++++++++++++++Interrupció de transmisió++++++++++++++++++++++++++++++++++ */
void __attribute__((__interrupt__, no_auto_psv)) _U1TXInterrupt(void)
{
IFS0bits.U1TXIF = 0;
}


/*++++++++++++++++++++++++++++++++++++ Interrepció de recepció++++++++++++++++++++++++++++++++++++++ */
void __attribute__((__interrupt__, no_auto_psv)) _U1RXInterrupt(void)
{

    IFS0bits.U1RXIF = 0; //baixa la bandera d'aquesta interrupció

/*
WriteTimer1(0x0);   
OpenTimer1(T1_ON
         & T1_GATE_OFF
         & T1_PS_1_1
         & T1_IDLE_STOP
         & T1_SYNC_EXT_OFF
         & T1_SOURCE_INT // antes INt
         , valor_a_comparar );


timer_value= ReadTimer1();*/

PORTBbits.RB5= 1;

   


   * Receiveddata = Buf[0];
   
   while( DataRdyUART1())  // condició a 1, mentres está rebent info
      {
         
   
      ( *( Receiveddata)++) = ReadUART1(); // d'aquesta manera em guarda el 3 bytes junts
        
   
   
       
      }
      
   if (Buf[0]==254)
    {

   f=0;
   }
   else
    {
   f=1;
//   Buf[0]=midi[0];
//   Buf[1]=midi[1];
//   Buf[2]=midi[2];
   
   }


/*   timer_value= ReadTimer1();
   if (timer_value<=0xFA) //FA
   {
      f=0;
      Buf[0]=0;
      PORTBbits.RB4= 1;
   }
   else
    {
   f=1;
   PORTBbits.RB0= 1;
   
   }         
      */


}











// +++++++++++++++++++++++++++++++++++++configuració modul UART per a MIDI+++++++++++++++++++++++++++++++
void configUSARTmidi() // cridarla en el main... o l'nterrupció
{
 unsigned int baudios, U1MODEvalue, U1STAvalue;
 ConfigIntUART1(UART_RX_INT_EN //RECEIVE INTERRUPT DISABLE
            & UART_RX_INT_PR2 //RECEIVE INTERRUPT PRIORITY
            & UART_TX_INT_EN // TRANSMIT INTERRUPT DISABLE
            & UART_TX_INT_PR6); // TRANSMIT INTERRUPT PRORITY
 baudios = 39; //AL REGISTRO UBRG calculado por mi ; (41 antes)
 U1MODEvalue = UART_EN  // UART ENABLE
          & UART_IDLE_STOP // MODO DE ESPERA
          & UART_RX_TX // COMUNICACIO AMB RX I TX
          & UART_DIS_WAKE // WAKE-UP  ON START
          & UART_DIS_LOOPBACK // LOOPBACK MODE.. originalemente en DIS
          & UART_DIS_ABAUD // INPUT TO CAPTURE MODULE
             & UART_NO_PAR_8BIT // PARIY AND DATA BITS SELECT
          & UART_1STOPBIT; //NUMBER O STOP BITS
 U1STAvalue =  UART_INT_TX_BUF_EMPTY // TRANSMISION MODE INTERRUPT SELECT
         & UART_TX_PIN_NORMAL // TRANSMIT BREAK BIT
         & UART_TX_ENABLE // TRANSMIT ENABLE
         & UART_INT_RX_BUF_FUL//UART_INT_RX_CHAR // RECEIVE INTERRUPT MODE SELECT
         & UART_ADR_DETECT_DIS //ADDRESS DETECT
         & UART_RX_OVERRUN_CLEAR; // OVERRUN BEAT CLEAR

 OpenUART1(U1MODEvalue, U1STAvalue, baudios);
//PORTBbits.RB3= 1;
}








//PROGRAMA PRINCIPAL
int main(void)
{



// ++++++++++++++++++++++++++ PARA LA UART ++++++++++++++++++++++++++++++++++++++++++++++++++

ConfigIntUART1(UART_RX_INT_EN // RECEIVE INTERRUPT ENABLE
         & UART_RX_INT_PR6 // RECEIVE INTERRUPT PRIORITY
         & UART_TX_INT_EN // TRANSMIT INTERRUPT ENABLE
         & UART_TX_INT_PR2); // TRANSMIT INTERRUPT PRIORITY

 configUSARTmidi();  //configuració per escriure i llegir RS232

//+++++++++++++++++++++PARA EL TIMER+++++++++++++++++++++++++++++++++++++++++++++++++++++

/*valor_a_comparar=0xFFFF;
OpenTimer1(T1_ON
         & T1_GATE_OFF
         & T1_PS_1_1
         & T1_IDLE_STOP
         & T1_SYNC_EXT_OFF
         & T1_SOURCE_INT // antes INt
         , valor_a_comparar );


ConfigIntTimer1( T1_INT_PRIOR_3 & T1_INT_OFF); */
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
   TRISBbits.TRISB0 =0;
   TRISBbits.TRISB1 =0;
   TRISBbits.TRISB2 =0;
   TRISBbits.TRISB3 =0;
   TRISBbits.TRISB4 =0;
   TRISBbits.TRISB5 =0;
   
// INICIALITZIÓ DE VARIABLES
   

   
   
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++



      PORTBbits.RB0= 0;
   PORTBbits.RB1= 0;   
   PORTBbits.RB2= 0;
   PORTBbits.RB3= 0;
   PORTBbits.RB4= 0;
   PORTBbits.RB5= 0;      
      
   PORTBbits.RB0= 1;

      
   Buf[0]=0;
//   Buf[1]='0';
//   Buf[2]='0';
   

      

      

while(1)
{
      //   PORTBbits.RB0= 1;
         while (f==0)
         {
         PORTBbits.RB1= 1;
         tiempo();
         PORTBbits.RB1= 0;
         }
          
   //      PORTBbits.RB2= 1;
         if (Buf[0]==0)
         {
         
         PORTBbits.RB3= 1;
         while (f==0);

         }
         if (Buf[0]==128)  //note off
         {
         
         PORTBbits.RB2= 1;
         while (f==0);
         }

         if (Buf[0]==144)  //note on
         {
         
      
         PORTBbits.RB4= 1;
         while (f==0);
         }
   
   
 

}   // BUCLE REPETITIU
}   // FI MAIN


/*Funcion delay paraq tiempo*/

void tiempo(void){
   int unsigned contador;
   int unsigned cont;
   for(cont=1;cont<20;cont++)
      for(contador=1;contador<0xFFFF;contador++);
   return;
}



a ver si encontrais el dichoso fallo, plis!!

Desconectado Sispic

  • Moderador Local
  • PIC24H
  • *****
  • Mensajes: 1685
    • winpic800
Re: Problemas leiendo midi con USART y c30, ayuda!!
« Respuesta #4 en: 04 de Abril de 2009, 07:38:05 »
Citar
  while( DataRdyUART1())  // condició a 1, mentres está rebent info
      {
         
   
      ( *( Receiveddata)++) = ReadUART1(); // d'aquesta manera em guarda el 3 bytes junts
       
   
   
       
      }

yo diria que en cada entrada de interrupcion solo puedes pillar un byte .
yo incrementaria un indice y comprobar si ha llegado a 3 etc .





     

Desconectado alogic.on

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 772
Re: Problemas leiendo midi con USART y c30, ayuda!!
« Respuesta #5 en: 04 de Abril de 2009, 08:11:40 »
hola, no programo en c :? pero yo lo que hago es (contandolo por encima) cada vez que llega un byte si el bit 7 está a 1 es una orden la clasifico por los 4 primeros bits si es un CC, note on... y si es el esperado activa un bit de señalizacion que en la proxima recepcion le hace saltar al programa a otra linea para procesar los datos.
 en el caso de un note on 1001 0000-1001 1111 testea el bit 7 es orden, testea los 4MSB es note on, en el siguiete byte sera el numero de nota de 0-127, y el siguiente el volumen de 0-127. espero te sirva  :mrgreen:

un saludo

Desconectado eusebioelmelenas

  • PIC10
  • *
  • Mensajes: 4
Re: Problemas leiendo midi con USART y c30, ayuda!!
« Respuesta #6 en: 04 de Abril de 2009, 20:42:26 »
Sispic! Lo que me dices puede ser verdad, que solo entre un byte..... lo probaré, en realidad quizás sea ese el problema,  según lo que yo tengo ahí arriba: ( no se citar)   " * Receiveddata = Buf[0]; " estoy poniendo el puntero a la primera palabra de la cadena.. y si cada vez entra a poner un byte, siempre lo pondrá en la primera palabra, y ya podia estar yo esperando que me marcara un "note on (0x90h)" o lo que sea... lo probaré..quizás sea eso...

void __attribute__((__interrupt__, no_auto_psv)) _U1RXInterrupt(void)
{

    IFS0bits.U1RXIF = 0; //baixa la bandera d'aquesta interrupció


   * Receiveddata = Buf[0];  POSIBLE ERROR!!!!!!!!!
   
   while( DataRdyUART1())  // condició a 1, mentres está rebent info
      {
         
   
      ( *( Receiveddata)++) = ReadUART1(); // d'aquesta manera em guarda el 3 bytes junts
       
   
      }
     

   }


Alogic, en un principio ya tenia en cuenta lo que me dices... pero es que no me llega nada de lo esperado.. lo que intentaba era comprobar más o menos lo que tu me decias con...

   if (Buf[0]==128)           //note off
         {
         
         PORTBbits.RB2= 1;
         while (f==0);
         }

         if (Buf[0]==144)       //note on
         {
         
     
         PORTBbits.RB4= 1;
         while (f==0);
         }
   
Lo que pasa que aquí lo comprobaba con el decimal. Más o menos es lo que quieres decir...

Un saludo gente! muy amables por perder el tiempo por aqui...



Desconectado Sispic

  • Moderador Local
  • PIC24H
  • *****
  • Mensajes: 1685
    • winpic800
Re: Problemas leiendo midi con USART y c30, ayuda!!
« Respuesta #7 en: 05 de Abril de 2009, 03:12:10 »
void __attribute__((__interrupt__, no_auto_psv)) _U1RXInterrupt(void)
{

    IFS0bits.U1RXIF = 0; //baixa la bandera d'aquesta interrupció

     Receiveddata[indice++] =U1RXREG;
   
    if(indice==3){
       //  han llegado 3
       indice = 0;       
       bla
    }
   

   }

yo lo veo asi .

U1STAbits.URXISEL = 0; // Interrupt after a character is received