Forum: Mikrocontroller und Digitale Elektronik Midi über Uart


von Mr-400-Volt (Gast)


Lesenswert?

Hallo, ich versuche schon länger ein Midi-Signal über die Uart
einzulehsen. Ich habe ein Midi-Keyboard über einen Optokoppler am
RXT-Pin angeschloßen, und die Bautrate auf 31250 gestellt. Dann hab ich
mich über das Midi-Protokoll informiert, und erfahren, das ich 3 bytes
einlesen muß. Und genau da liegt mein Problem. Wie lese ich diese 3
Bytes richtig ein ( mit Bascom ) ? Muß das irgendwie Syncronisiert
werden ? Für Hilfe bin ich sehr Dankbar!!!

von mmerten (Gast)


Lesenswert?

Dann schau dir das Midi Protokoll nochmal genau an. Bei den typischen 3
Byte Sequenzen (Note on/ff) ist beim 1. Byte immer das 8. Bit gesetzt.

von Mr-400-Volt (Gast)


Lesenswert?

Muß ich dann das 8te bit abfragen ob es gesetzt ist, und wenn ja die
anderen 2 hintereinander einlesen ?

von Mr-400-Volt (Gast)


Lesenswert?

Hmmm, der folgende Code geht leider auch nicht. Ich trete irgendwie auf
der Stelle. Könnte mir jemand weiter helfen ? Wie beckomme ich
wenigstens das erste (Statusbyte) richtig eingelesen ???

Danke !


$regfile = "m16def.dat"
$crystal = 12000000
$baud = 31250

Dim I(3) As Byte , A As Byte , X As Byte

Cls

X = 0

Do



   A = Udr
   If A.7 = 1 Then
      I(1) = Udr
   End If
   A = Udr
   If A.7 = 1 Then
      I(2) = Udr
   End If
   A = Udr
   If A.7 = 1 Then
      I(3) = Udr
   End If





   Locate 1 , 1
   Lcd Bin(i(1))
   Locate 2 , 1
   Lcd I(2)
   Locate 3 , 1
   Lcd I(3)


Loop

von inoffizieller WM-Rahul (Gast)


Lesenswert?

Vielleicht solltest du darauf warten (abfragen), ob überhaupt etwas
neues empfangen wurde.

A = Udr
Liest einfach nur das UDR aus und schreibt es in die Variable A.
Das kann man zu jeder Zeit machen, auch wenn die USART überhaupt nicht
benutzt wird.

von Profi (Gast)


Lesenswert?

Ich habe auch mal einen Midi-Analyzer programmiert, ist gar nicht so
einfach. Stelle Dir das ganze Midi-Protokoll wie eine große
State-Machine vor.

Warte auf ein Byte, untersuche es und springe davon abhängig in einen
anderen State.
Mit den drei hintereinanderfolgenden if-Abfragen wie in Deinem Beispiel
klappt das nicht, da Du keine States hast.

Wenn mich nicht alles täuscht, habe ich -nachdem ich es in Pascal
programmiert hatte- im Netz ein ganz ähnliches C-Programm gefunden.

Soll ich es Dir heraussuchen?

von Mr-400-Volt (Gast)


Lesenswert?

Mit C kenne ich mich nicht aus, meint Ihr eine :
if Usr.rxc = 1 then......abfrage ?

von inoffizieller WM-Rahul (Gast)


Lesenswert?

sowas in der Richtung. Und das am besten in einer Schleife solange
abfragen bis RXC gesetzt ist.

von Mr-400-Volt (Gast)


Lesenswert?

Oh mann, ich werd noch.....
geht auch nich...

Do

   If Usr.rxc = 1 Then
      I(1) = Usr
         If I(1).7 = 0 Then
         If Usr.rxc = 1 Then
            I(2) = Usr
               If I(2).7 = 0 Then
               If Usr.rxc = 1 Then
                  I(3) = Usr
               End If
               End If
               End If
               End If
   Locate 1 , 1
   Lcd Bin(i(1))
   Locate 2 , 1
   Lcd I(2)
   Locate 3 , 1
   Lcd I(3)
   End If


Loop

von inoffizieller WM-Rahul (Gast)


Lesenswert?

do
loop until USR.RXC = 1

I(1) = UDR

if I(1).7 = 1 then...

Ist das so schwer?

von Rolf Meurer (Gast)


Lesenswert?

Es sind nicht immer 3 Byte Befehle:
Es gibt auch 2 Byte Befehle, z.B. channel Aftertouch, ProgrammChange
sowie auch 1 Byte Befehle, z.B. MIDI Clock, Start, Stop, Continue, Tune 
Request.
Nicht zu vergessen MTC, da sind es 32 Bytes, noch schlimmer wird's bei 
SysEx Befehlen, da ist die Anzahl der Bytes ungewiss. Man weiß erst nach 
Eintreffen von F7 wie viele Bytes eingetrudelt sind.
Dann ist auf jeden Fall noch der Running Status zu berücksichtigen, 
wobei Status-redundanten Channel Befehle nicht gesendet werden und zwar 
so lange bis der Status gewechselt wird. Ausnahme sind System- und 
Realtime messages. All dies muss berücksichtigt werden um einen 
MIDI-Analyzer erfolgreich zu programmieren.
Ist aber kein Hexenwerk.
Man muss nur die eingehenden Daten in der richtigen Reihenfolge 
abfragen.
1st System messages, alle Daten & 0xF0
2nd Channel messages, alle Daten & 0x80
3rd running status, dazu am besten eine eigene RS_Byte Variable 
verwenden:

RS_Byte is cleared at power up
RS_Byte stores the status when a ChannelMessage 0x80...0xEF is received.
RS_Byte is cleared when a SystemMessage 0xF0...0xF7 is received.
Nothing is done to RS_Byte when a RealTimeMessage is received.
Any data bytes are ignored when RS_Byte is cleared.

Das sollte helfen

lg Rolf

von Rolf M. (rmagnus)


Lesenswert?

Rolf Meurer schrieb:
> Das sollte helfen

Nach 13(!) Jahren ist zu hoffen, dass der TE es auch so schon geschafft 
hat.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.