Hallo, ich habe ein Übertragungsproblem mit Midi. Und zwar habe ich bei
meinem ATmega644p zwei UART´s, wobei ich auf den ersten (RXD0 und TXD0)
zwei MIDI-Buchsen für TX und RX gehängt habe. Als Taktgeber verwende ich
übrigens den internen 8Mhz Oszillator.
Nun gehe ich in die while(1)-Schleife in der Main-Funktion, und schiebe
dort ein ASCII-Zeichen, ( in meinem Fall 0b01010101 ) in das
Sende-Register (UDR0), das mir dann das entsprechende UART-Signal auf
dem TXD0-Pin mit Midi-Baudrate von 31250 ausgibt. Siehe Anhang
"31250_BAUD_TXD0_Start.png"
Hier sieht das Signal noch schön aus....
Jetzt habe ich aber die zwei Midi-Buchsen die ja auf RXD0 und TXD0
hängen mit einem Midi-Kabel verbunden. Also kurzgeschlossen.
(PS: Die Sende-und Empfangsschaltung habe ich aus dem
Mikrocontroller-Beitrag
https://www.mikrocontroller.net/articles/MIDI".)
Oder Siehe Anhang "Midi Sender.png" und "Midi Empfänger.png"...hier habe
ich beim Sender 220 Ohm Widerstände verwendet, weil ich ja eine 5V
Spannungsversorgung habe.
Aber abgesehen davon sieht mein UART-Signal, nachdem es durch die
Leitung gegangen ist, und durch den Optokoppler (PC900V) gewandert ist,
folgendermaßen aus: Anhang "31250_BAUD_RXD0_Ende.png"
Dabei ist das Midi-Kabel noch sehr kurz gewählt (geschätzt 1m).
Sobald aber bei RXD0 ein komplettes Byte übertragen wurde, wird bei mir
ein Interrupt ausgelöst, und das Empfangene Zeichen auf den 2ten UART,
den der Mikrocontroller besitzt ausgegeben, also ins Register UDR1
geschrieben (Also bei PIN TXD1 ausgegeben). Wenn ich dort jetzt das
Signal mit dem Oszilloskop messe, sieht es so aus: Anhang
"31250_BAUD_TXD1_Ausgabe.png"
Leider wird, wie man sicher an den Screenshots erkennen kann, das Signal
verfälscht, und so falsch wiedergegeben. Woran kann das liegen ? Ich
nehme an der Hardware, oder ?? Was kann ich beim Schaltplan ändern ??
Sicherheitshalber befindet sich hier noch der µC-Code:
Danke vielmals schon im Voraus,
mfg Felix
1 | #define F_CPU 8000000UL
|
2 | #define USART_BAUDRATE_0 31250
|
3 | #define USART_BAUDRATE_1 31250
|
4 |
|
5 | #define BAUD_PRESCALER_0 (((F_CPU / (USART_BAUDRATE_0 * 16UL))) -1)
|
6 | #define BAUD_PRESCALER_1 (((F_CPU / (USART_BAUDRATE_1 * 16UL))) -1)
|
7 |
|
8 | #include <avr/io.h>
|
9 | #include <util/delay.h>
|
10 | #include <avr/interrupt.h>
|
11 |
|
12 | void uart0_init(void);
|
13 | void uart1_init(void);
|
14 |
|
15 | int main(void)
|
16 | {
|
17 | _delay_ms(1000);
|
18 | uart0_init();
|
19 | uart1_init();
|
20 | sei();
|
21 |
|
22 | while (1)
|
23 | {
|
24 | UDR0 = 0b01010101; //Das Signal, dass durch das 1 meter lange Midi-Kabel geschickt wird...
|
25 | }
|
26 | }
|
27 |
|
28 | ISR(USART0_RX_vect) //Der Interrupt, der ausgelöst wird, wenn bei der Midi-Eingangsbuchse ein Byte angekommen ist
|
29 | {
|
30 | char data = UDR0; //Das empfangene Byte schnell speichern
|
31 | UDR1 = data; //Hier wird das empfangene Byte beim anderen UART-TX-Pin wieder ausgegeben
|
32 | }
|
33 |
|
34 |
|
35 | void uart0_init(void)
|
36 | {
|
37 | UCSR0B |= (1<<TXEN0); // uart Transmitter enable -> senden (Hier hängt die Midi-Ausgangsbuchse)
|
38 | UCSR0B |= (1<<RXEN0); // uart Receiver enable -> empfangen (Hier hängt die Midi-Eingangsbuchse)
|
39 | UCSR0B |= (1<<RXCIE0); //Receive Complete Interrupt Enable (Der Interrupt, wenn bei der Midi-Eingangsbuchse ein Byte angekommen ist)
|
40 |
|
41 | UBRR0H = (BAUD_PRESCALER_0>>8);
|
42 | UBRR0L = BAUD_PRESCALER_0;
|
43 | }
|
44 |
|
45 | void uart1_init(void)
|
46 | {
|
47 | UCSR1B |= (1<<TXEN1); //Zum Ausgeben des Signals, um es am Ende kontrollieren zu können.
|
48 |
|
49 | UBRR1H = (BAUD_PRESCALER_1>>8);
|
50 | UBRR1L = BAUD_PRESCALER_1;
|
51 | }
|