Hallo Mitstreiter,
ich bin hier am verzweifeln und hoffe auf einen Hilfreichen Tipp.
Ich kann leider Nur Assembler und damit habe ich auch schon viel
erreichen können.
Es geht mir um das Ausgeben einer MIDI-Note.
Ich habe schon einiges zu dem Thema gefunden und normalerweise sollte es
recht einfach gehen. Dennoch gelingt es mir nicht, einen Ton aus dem
01R/W zu bekommen.
Ich schließe meine Keyboard an den 01R/W an und betätige die Taste für
ein A (440Hz) und die Empfangs Led am 01R/W blinkt auf und auch der Ton
wird höhrbar.
So weit, so gut.
Nun schließe ich meine Schaltung an und auch bei mir blinkt die Empfangs
Led aber es wird kein Ton hörbar. Cubasis empfängt auch keine Noten ...
Mit dem Oszi werden 3 gesendete Bytes erkennbar und ein Bit braucht 33µs
Am Keyboard sind es auch 33µs
Vieleicht hat ja einer von euch eine Idee...
Ich dachte mir, Mit dem ATMega 32 sollte es kein Problem sein.
**** 1. Bautrate ermitteln:
;Variabelen und Vorgabewerte
.equ TAKT = 8000000 ; Systemtakt 8.000 MHz
.equ BAUD = 31250 ; Baudrate für MIDI
; Berechnungen
.equ UBRR_VAL = ((TAKT+BAUD*8)/(BAUD*16)-1) ; clever runden
.equ BAUD_REAL = (TAKT/(16*(UBRR_VAL+1))) ; Reale Baudrate
.equ BAUD_ERROR = ((BAUD_REAL*1000)/BAUD-1000) ; Fehler in Promille
.if ((BAUD_ERROR>10) || (BAUD_ERROR<-10)) ; max. +/-10 Promille
Fehler
.error "Systematischer Fehler der Baudrate grösser 1 Prozent und damit
zu hoch!"
.endif
**** 2. Bautrate in Register ablegen
; Baudrate einstellen
ldi akku, HIGH(UBRR_VAL)
out UBRRH, akku
ldi akku, LOW(UBRR_VAL)
out UBRRL, akku
**** 3. UART konfigurieren
; Frame-Format: 8 Bit
; ldi akku, (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0)
; out UCSRC, akku
; Abgeschaltet da in Midirec auch nicht gewesen
sbi UCSRB,TXEN ; TX aktivieren
**** 4. 3 Byte Vorbereiten:
lds akku, 0b01101111 ; Note on CH1
sts MIDI1, akku
lds akku, 0b10000101 ; Note A4 (69 MIDI = 45 Hex)
sts MIDI2, akku
lds akku, 0b10000000 ; minimale Lautstärke (0) (Note off)
sts MIDI3, akku
**** 5. 3 Byte senden
MIDIout:
push akku
MIDIout1:
sbis UCSRA,UDRE ; Warten bis UDR für das nächste
; Byte bereit ist
rjmp MIDIout1
LDS akku, MIDI1
out UDR, akku
MIDIout2:
sbis UCSRA,UDRE ; Warten bis UDR für das nächste
; Byte bereit ist
rjmp MIDIout2
LDS akku, MIDI2
out UDR, akku
MIDIout3:
sbis UCSRA,UDRE ; Warten bis UDR für das nächste
; Byte bereit ist
rjmp MIDIout3
LDS akku, MIDI3
out UDR, akku
pop akku
ret
**** und zum Schluss
.DSEG
MIDI1: .BYTE 1 ; MIDI - Befehl/Kanal
MIDI2: .BYTE 1 ; MIDI - Controlernummer(Note)
MIDI3: .BYTE 1 ; MIDI - Controlerwert (Lautstärke)
Ich hoffe Ihr könnt mir folgen,
Liebe Grüße und vielen Dank
Walter
Ein Bit dauert 32 Mikrosekunden. Du schickst im 2. Byte nicht 45, sondern 85. Lautstärke 0 oder 80? Kommentar muss immer zum Code passen. Manche Geräte schicken statt Note off ein Note on mit Lautstärke 0. Passt die Polarität? Normal fließt kein Strom in der Schleife.
Walter schrieb: > lds akku, 0b01101111 ; Note on CH1 > sts MIDI1, akku > lds akku, 0b10000101 ; Note A4 (69 MIDI = 45 Hex) > sts MIDI2, akku > lds akku, 0b10000000 ; minimale Lautstärke (0) (Note off) > sts MIDI3, akku Warum gibst Du die Werte der Bytes binär an? Wenn Du es dann wenigstens selbst korrekt ausgerechnet hättest... Also, das Statusbyte für "Note On Ch1" ist 0x90 (= 0b10010000) - Deins scheint (warum auch immer) invertiert zu sein. 0x45 ist 0b01000101 - Deins ist 0x85 (=>Statusbyte "Note off on Ch 6") Dein Velocity-Wert 0 würde (wenn er richtig codiert wäre - tatsächlich sendest Du 0x80 = Statusbyte Note Off on Ch1) als "Note Off" interpretiert - da müsstest Du Dich auch nicht wundern, wenn Du nix hörst. Probier's mal mit mittlerem Velocity-Wert, also 0x40. Bei der obigen Sequenz also: > lds akku, 0x90 ; Note on CH1 > sts MIDI1, akku > lds akku, 0x45 ; Note A4 (69 MIDI = 45 Hex) > sts MIDI2, akku > lds akku, 0x40 ; mittlere Lautstärke 64 > sts MIDI3, akku
> lds akku, 0x90 ; Note on CH1 > sts MIDI1, akku > lds akku, 0x45 ; Note A4 (69 MIDI = 45 Hex) > sts MIDI2, akku > lds akku, 0x40 ; mittlere Lautstärke 64 > sts MIDI3, akku Da muss doch jeweils ldi stehen statt lds, oder?
Hallo, zusammen,
das ist ja der Hammer! Wer wird mir schon helfen? Und dann so schnell!
Ganz herzliches Dankeschön! Super Kommentare und es läuft.
Aber für alle die das Gleiche erleben, hier noch mal konkret:
Ich war so verzweifelt und suchte nach jedem Halm. In einem der Beiträge
war erwähnt, dass die Bits invertiert werden müssen – ein Versuch
zeigte, dass es deshalb trotzdem nicht klappte. Ich vergas die
Invertierten Bits zurück zu schreiben!
Also Rüffel zu Recht und sorry!
; **** Note on:
ldi akku, 0b10010000 ; Note on und CH1 (000)
sts MIDI1, akku
ldi akku, 0b00100100 ; Note C1 (36 MIDI = 25 Hex)
sts MIDI2, akku
ldi akku, 0b01111111 ; maximale Lautstärke (127) (Note on)
sts MIDI3, akku
call MIDIout
; **** Note off:
ldi akku, 0b10010000 ; Note on und CH1 (000)
sts MIDI1, akku
ldi akku, 0b00100100 ; Note C1 (36 MIDI = 25 Hex)
sts MIDI2, akku
ldi akku, 0b00000000 ; minimale Lautstärke (0) (Note off)
sts MIDI3, akku
Mein Fehler bestand tatsächlich in dem LDS ... ganz klar, den akku läd
man mit einer Zahl mit "ldi" und schon spielt die Musik! - Naja - die
Note ;-)
Übrigens angeregt durch den Beitrag "MIDI-Controller selber bauen" von
Götz Müller-Dürholt
https://www.youtube.com/watch?v=a6pex3DwNjs
baue ich ein Gerät zum wiedergeben von Wierderständen in Form von
Midinoten.
Also nochmals Danke für die absoulut korrekte und sehr ziehführende
Hilfe!
Viele Grüße
Walter
Ok, das mit dem LDS vs. LDI wäre mir vielleicht auch aufgefallen, wenn ich mehr mit AVRs zu tun hätte... ;) Deinen Hang zu Zahlenwerten im Binärsystem kann ich immer noch nicht nachvollziehen. Das macht es hier doch nur unleserlich und fehleranfällig. Beim MIDI Statusbyte bietet sich hexadezimale Schreibweise an (erstes Digit = Funktion, z.B. 9 = Note On, zweites Digit: MIDI-Kanal 0..F -> K.1..16), Notennummer und Velocitywert könnte man auch dezimal angeben - was soll hier die Binärdarstellung?
Hallo Thomas, ja, Du hast recht, die Hex darstellung ist sehr schön. Ich war nur auf der Fehlersuche und wollte die seriellen Bits mit dem Bild vom Oszi vergleichen und da kann ich mir besser vorstellen wie das Signal aussehen muss :-)
Wie kann man leider nur assembler können? C ist viel einfacher und schnell gelernt, wenn man eh weiß was sich unter dem Blech abspielt.
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.