Hallo, ich möchte ganz einfach ein paar MIDI-Daten an ein Keyboard senden. Leider komme ic nicht zum Ziel. Vielleicht bin ich auch schon ein wenig betriebsblind -- so dass der Fehler ganz nah liegen könnte. Ich habe Wahlweise einen ATmega8 bzw. einen ATmega8535 mit je 6MHz. Compiler: AVR-Studio mit GCC/WinAVR Mein Quellcode: #include <avr/io.h> #include <inttypes.h> #include <stdio.h> #include <avr/pgmspace.h> #include <util/delay.h> #define F_CPU 6000000UL #define BAUD 31250UL #define UBRR_BAUD ((F_CPU/(16UL*BAUD))-1) // USART initialisieren void uart_init(void) { // Baudrate einstellen (Normaler Modus) UBRRH = (uint8_t) (UBRR_BAUD>>8); UBRRL = (uint8_t) (UBRR_BAUD); // Aktivieren vom transmitter UCSRB = (1<<TXEN); // Einstellen des Datenformats: 8 Datenbits, 1 Stoppbit UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0); } int main(void) { uint8_t buffer; // USART initialisieren uart_init(); while (1) { // Warten bis der Sendepuffer frei ist while ( !( UCSRA & (1<<UDRE)) ); // Daten in den Puffer schreiben und damit senden buffer = 0x91; UDR = buffer ; _delay_ms(10); // Warten bis der Sendepuffer frei ist while ( !( UCSRA & (1<<UDRE)) ); // Daten in den Puffer schreiben und damit senden buffer = 0x3C; UDR = buffer ; _delay_ms(10); // Warten bis der Sendepuffer frei ist while ( !( UCSRA & (1<<UDRE)) ); // Daten in den Puffer schreiben und damit senden buffer = 0x7F; UDR = buffer ; _delay_ms(10); } } PD1(TXD) --> Pin 4 der MIDI Buchse +5V --> Pin 4 der MIDI Buchse jeweils über 220R Auf dem Oszilloskop kann man die einzelnen gesetzten Bits auszähen. Es sieht auf dem ersten und zweiten Blick nicht verkehrt aus. Im Moment lese ich die gesendeten Daten mit einem MIDI-USB-Übertrager aus. Leider erhalte ich nur Müll, obwohl die EmpfangsLED leuchtet. Kann mir jemand sagen, was ich falsch gemacht habe?? Vielen Dank und viele Grüße
Entschuldigung, ein kleiner Fehler. Es muss natürlich so sein: PD1(TXD) --> Pin 5 der MIDI Buchse +5V --> Pin 4 der MIDI Buchse
Japp - zusätzlich durch Oszi verifiziert. --> Es ergibt sich eine Bitbreite von ca. 32µs. Gruß Sebastian
Wieso wartest Du eigentlich immer 10ms ? Du könntest doch in der Zeit schon längst wieder senden.
Sende doch mal nur ein einzelnes Byte und schaue was der MIDI-Usb-Übertrager macht. So spontan kann ich auch keinen Fehler im Code finden. Gruß Christian
Hallo, ich habe immer 10ms dazwischen gesetzt, damit man auf dem Oszi die Bits besser auszählen kann. Auch wenn ich nur 1 Byte sende wird nur Müll erkannt. Der USB-Umsetzer ist soweit ich das beurteilen kann in Ordnung, da das Einspeisen von anderen MIDI-Quellen problemlos funktioniert. Gruss Sebastian
Hallo, ich würde gerne mit Bascom Midi-Befehle senden. soweit ich das kapiert habe, hat midi eine baudrate von 3125 Baud. stimmt das? mein code: ------------------------------------------------------------------------ ----- $regfile = "m8def.dat" $crystal = "8000000" Baud = 3125 Do print chr(144) ; chr(60) ; chr(64) 'Taste C drücken (Kanal 0) print chr(128) ; chr(60) ; chr(64) 'Taste C loslassen (Kanal 0) wait 1 Loop End ------------------------------------------------------------------------ ----- quelle der midi-codes: http://web.archive.org/web/20071005165328/www.borg.com/~jglatt/tech/midispec/noteon.htm funktioniert der so? mfg cyberlink
@ cyberlink >Hallo, ich würde gerne mit Bascom Midi-Befehle senden. >soweit ich das kapiert habe, hat midi eine baudrate von 3125 Baud. >stimmt das? Nicht ganz. Sie beträgt 31,25 kBauds, so wie es oben steht.
>hat midi eine baudrate von 3125 Baud.
Wo hast du diese Info her ?
Und überlege Dir mal wie lange die Taste C in Deiner Schleife in etwa
gedrückt bleibt.
Hallo, erstaunlicher Weise funktioniert die Lösung mit BASCOM (Baud = 31250). Daraus schlussfolgere ich, dass meine Peripherie und Pinbelegung richtig sind. Dann kann ja nur noch mein Quellcode falsch sein... Gruß Sebastian
@ Sebastian Die Fragen kann ich mir wahrscheinlich sparen: ohne die beiden ersten _delay_ms(10) hast Du es sicher auch schon probiert, oder?
Japp, ohne gehts auch nit. Die Zeiten dienen nur zum besseren anschauen auf dem Oszi. Gruß
Das ist ein komisches Problem. Mir fällt auf, dass das BASCOM Beispiel den Kanal 0 benutzt, während du im C Beispiel Kanal 1 hast. Kann es sein, dass das Keyboard auf Monophonie eingestellt ist? Meine andere Idee ist, dass vielleicht der Ton einen langsamen Attack hat und du deshalb nichts hörst, weil der Ton in Sekundenbruchteilen wieder neu startet.
Hallo, da jetzt mein quellcode fertig ist (mini-synthesizer mit tastern) würde ich mich jetzt mal an den Anschluss meines Keyboards machen. Also dass der AVR MIDI-Daten sendet und das Keyboard sie über den MIDI-IN Port empfängt. Auf wikipedia hab ich folgende Anschlussbelegung gefunden: http://de.wikipedia.org/wiki/Bild:StandardMIDIInterface.gif Diese ist aber offensichtlich für den Gameport, der sicher wieder einen anderen Signalpegel hat. Midi hat ja einen Signalpegel von 5 Volt (0) oder 0 Volt (1). Das ist genau der UART Pegel des AVR, nur negativ. Wie bekommt man so etwas am einfachsten (kleiner Bauteileaufwand, Bastelkistenteile) hin? Vielleicht mit zwei Optokopplern? Das IC in der Wikipediaschaltung (falls das mit dem AVR funktionieren würde) müsste ich nämlich erst bestellen. Ich hoffe, ihr könnt mir helfen mfg cyberlink
AVR TXD über 220 Ohm an die MIDI-Buchse (Ausgang) und den anderen Pol der MIDI-Buchse über 220 Ohm an Vcc. Vom externen Keyboard an die MIDI-Buchse (Eingang) über 220 Ohm an die Anode der LED eines Optokopplers (CNY17/1 reicht) und deren Kathode zum anderen Pol der Buchse, dessen Emitter an Masse, Kollektor an AVR RXD und einen PullUp von 470 Ohm an Vcc. Das war´s.
Hallo zusammen, ist schon ein altes Thema. Ich mach deshalb keinen neuen Thread auf, in der Hoffnung, dass das trotzdem jemand liest. Ich bin gerade dabei einen MIDI Controller zu basteln. Noch befindet sich alles im Aufbau. Ich würd gerne aus Testzwecken einzelne MIDI Messages an den PC senden. Der Aufbau ist folgender: uC: atmega8 taktgeber quarz: 12 MHz Fuses gesetzt (low: FF, high: C9) MIDI Schnittstelle gebaut und verkabelt nach Plan (Pin4 der Buchse über 220 ohm an TXD, Pin2 an GND, Pin5 über 220 an Vcc 5V) programmiert mit Codevision Mit MidiOX prüfe ich, was am PC ankommt. Leider tut sich rein gar nichts. Ich weiß nicht, ob es am Code liegt, oder am uC... ich bin ratlos. Hier der Code in abgespeckter Form. Könnt ihr irgendwo einen Fehler entdecken? Hab ich vergessen notwendige Details zu erwähnen? Ich wäre für eure Hilfe sehr sehr dankbar.
1 | Chip type : ATmega8 |
2 | Program type : Application |
3 | Clock frequency : 12,000000 MHz |
4 | Memory model : Small |
5 | External RAM size : 0 |
6 | Data Stack size : 256 |
7 | *****************************************************/ |
8 | |
9 | #include <mega8.h> |
10 | #include <delay.h> |
11 | |
12 | // Standard Input/Output functions |
13 | #include <stdio.h> |
14 | |
15 | |
16 | unsigned char buffer; |
17 | |
18 | void putchar_midi_on() |
19 | { |
20 | |
21 | while ( !( UCSRA & (1<<5)) ); |
22 | buffer = 0x91; |
23 | UDR = buffer ; |
24 | |
25 | while ( !( UCSRA & (1<<5)) ); |
26 | buffer = 0x50; |
27 | UDR = buffer ; |
28 | |
29 | while ( !( UCSRA & (1<<5)) ); |
30 | buffer = 0x64; |
31 | UDR = buffer ; |
32 | |
33 | } |
34 | |
35 | void putchar_midi_off() |
36 | { |
37 | while ( !( UCSRA & (1<<5)) ); |
38 | buffer = 0x81; |
39 | UDR = buffer ; |
40 | |
41 | while ( !( UCSRA & (1<<5)) ); |
42 | buffer = 0x50; |
43 | UDR = buffer ; |
44 | |
45 | while ( !( UCSRA & (1<<5)) ); |
46 | buffer = 0x64; |
47 | UDR = buffer ; |
48 | } |
49 | |
50 | |
51 | void main(void) |
52 | { |
53 | |
54 | [...] |
55 | |
56 | // Port D initialization |
57 | PORTD=0xFF; |
58 | DDRD=0xFF; |
59 | |
60 | [...] |
61 | |
62 | // USART initialization |
63 | // Communication Parameters: 8 Data, 1 Stop, No Parity |
64 | // USART Receiver: Off |
65 | // USART Transmitter: On |
66 | // USART Mode: Asynchronous |
67 | // USART Baud Rate: 31250 |
68 | UCSRA=0x00; |
69 | UCSRB=0x08; |
70 | UCSRC=0x86; |
71 | UBRRH=0x00; |
72 | UBRRL=0x17; |
73 | |
74 | [...] |
75 | |
76 | while (1) |
77 | { |
78 | |
79 | if(!(PINC&0b00000001)) //Button an pinc0 |
80 | { |
81 | putchar_midi_on(); |
82 | |
83 | PORTD&=~(0b00000100); //Kontroll LED an |
84 | delay_ms(100); |
85 | PORTD|=0b00000100; //Kontroll LED aus |
86 | //LEDs dienen nur temporär zum Überprüfen, ob die Fkt aufgerufen wird |
87 | } |
88 | |
89 | if(!(PINB&0b00000100)) //Button an pinb2 |
90 | { |
91 | putchar_midi_off(); |
92 | |
93 | PORTD&=~(0b00000100); |
94 | delay_ms(100); |
95 | PORTD|=0b00000100; |
96 | |
97 | }; |
98 | } |
99 | } |
weiß keiner eine lösung? hier nochmals die bitte drüber zu sehen. besten dank!
Als erstes würde ich am MIDI-Ausgang Deines Controllers eine LED anschließen und gucken, ob sie blinkt. Dann wäre noch interessant, wie Du Deinen MIDI-Ausgang mit dem PC verdrahtet hast.
http://www.embedds.com/diy-midi-interface-for-usb/ Guck mal hier, ich habe die Orginale Internetseite nicht mehr gefunden. Aber vielleicht hilft dir der Code zu dem projekt weiter http://www.avrfreaks.net/index.php?module=Freaks%20Files&func=viewFile&id=2515&showinfo=1
Hallo und vielen Dank für die Antworten. @travelrec, dass daten fließen, habe ich mit nem multimeter gemessen. ich weiß, das ist nicht die genaueste Methode, aber es hat gereich um festzustellen, dass was passiert am Ausgang. An die MIDI (DIN) Buchse habe ich ein einfaches MIDI Kabel angeschlossen, welches dann zur seriellen Schnittstelle meiner Soundkarte führt, als Adapter sozusagen. Soundkarte ist die Terratec EWX 24/96. Die haben damals einen "Gameport" mitgeliefert als "Midi In". Mein MIDI Keyboard tut's auch einwandfrei, daran liegts also nicht. @phil, vielen Dank für den Beispiel Code. Nachdem ich drüber gesehen habe, hab ich, abgesehen vom Umfang, keinen Unterschied zu meinem Code entdeckt... leider. Hm... ich frag mich, ob ich das mit der Bitübertragung richtig eingestellt habe. 8 Daten Bits, 1 Stop Bit, kein Parity Bit ist doch korrekt, oder? Was ist mit dem Startbit? Und wieso steht im Beispielcode etwas von Stop Bit Generation?:
1 | void SUART_putchar( u8 val ) // send byte |
2 | { |
3 | while( stx_count ); // until last byte finished |
4 | stx_data = ~val; // invert data for Stop bit generation |
5 | stx_count = 10; // 10 bits: Start + data + Stop |
6 | } |
Das verwirrt mich. Was hat es damit auf sich? Hab auch in Büchern nix dazu gefunden. Vielleicht liegt es daran, dass etwas fehlt bei der Übertragung, oder etwas falsch interpretiert wird...
Moment mal: benutzt Du nun eine Hardware- oder Software-UART? Bei der Hardware-UART mußt Du nur Baudratenregister und Steuerregister passend setzen und nacheinander die richtigen Bytes in das UDR-Register schreiben. Die Baudrate muß natürlich stimmen. Den Rest mit Start und Stop-Bit macht die Hardware.
Thomas P. schrieb: > 8 Daten Bits, 1 Stop Bit, kein Parity Bit ist doch korrekt, oder? Was > ist mit dem Startbit? Ich weiß, es ist ein altes Thema. Aber ich beschäftige mich gerade auch damit. Erwartet MIDI tatsächlich ein Stop Bit? Nach dem hier: http://de.wikipedia.org/wiki/Musical_Instrument_Digital_Interface#Funktionsweise_des_MIDI-Protokolls werden doch nur bloße Bytes gesendet, oder? Die Unterscheidung Status-/Datenbyte erfolgt mit dem ersten Bit eines Bytes.
Mark M. schrieb: > Nach dem hier: > http://de.wikipedia.org/wiki/Musical_Instrument_Di... > werden doch nur bloße Bytes gesendet, oder? Das hat damit nichts zu tun. Es geht um die grundlegende serielle Übertragung, Start- und Stopbit gehören zu deren Framing, das um jedes übertragene Byte gepackt wird. Darum muss man sich als Programmierer nicht kümmern, das erledigt die UART-Hardware ganz von selbst.
Rufus Τ. Firefly schrieb: > Mark M. schrieb: >> Nach dem hier: >> http://de.wikipedia.org/wiki/Musical_Instrument_Di... >> werden doch nur bloße Bytes gesendet, oder? > > Das hat damit nichts zu tun. Es geht um die grundlegende serielle > Übertragung, Start- und Stopbit gehören zu deren Framing, das um /jedes/ > übertragene Byte gepackt wird. > > Darum muss man sich als Programmierer nicht kümmern, das erledigt die > UART-Hardware ganz von selbst. Aber hier geht es doch darum, MIDI-Bytes an einen MIDI-Eingang zu senden. Und ich habe gedacht, dass MIDI eben kein Framing hat/braucht. Oder versteht es UART mit Start- und Stop-Bits? Steht das irgendwo?
Mark M. schrieb: > Und ich habe gedacht, dass MIDI eben kein Framing hat/braucht. Doch, tut es. Das ist eine ganz stinknormale UART-Übertragung, so, wie es asynchrone serielle Schnittstellen tun. Es "versteht" nicht nur Start- und Stopbits, es benötigt sie zwingend. Wäre die serielle Schnittstelle des PCs in der Lage, die korrekte Baudrate zu erzeugen, müsste man nur von RS232-Pegeln auf die MIDI-Stromschnittstelle umsetzen und könnte direkt mit MIDI-Hardware kommunizieren.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.