Forum: Mikrocontroller und Digitale Elektronik DMX senden in C, interrupt-Frage


von Jannis A. (jannis_)


Angehängte Dateien:

Lesenswert?

Hallo!
Vorneweg: Ich hab das Forum nach Einträgen mit DMX im Titel durchsucht 
und alle bis ca 2005 gelesen. Und: Ich kenne die AVRs, mag sie auch, 
will das aber mit diesem Board schaffen. Assembler kann ich bedingt 
lesen, nicht schreiben und die Seiten von Holger dazu kenne ich :)

Ich versuche seit gestern DMX-Daten mit dem EUROScope-Board von Fujitsu 
zu senden. Darauf ist ein Fujitsu 96F340HSB mit 56MHz. Inzwischen bin 
ich soweit, dass das DMX-Signal auf dem Oszi gut aussieht, hier kurz die 
Beschreibung des Algorithmus, bevor ihr euch durch den Code quält:
1. UART aus, PIN auf high level, Timer-Reload auf > 100us (Mark before 
break)
2. PIN auf low, Timer-Reload auf 176us (Break)
3. PIN auf high, Timer-Reload auf ca 50us (Mark after Break)
4. UART an, Null-Byte in Senderegister, Timer-Reload auf 39us
5. SOLANGE warten bis Senderegister leer, DMX-wert rein BIS alle 
DMX-Werte gesendet

Klappt auch soweit ganz gut, nur ich will die Daten ja auch ändern, also 
UART0 (DMX sende ich auf UART1) mit ISR verbinden und immer wenn Daten 
reinkommen, diese auswerten. Klappte nicht ganz. Nun zum Test: In der 
main() eine LED togglen lassen. Ergebnis auf dem Oszi (siehe Foto): Die 
LED wird nur getoggelt, wenn DMX zwischen zwei Paketen steht, nicht aber 
wenn Bytes gesendet werden. Okay, da bekomme ich alle 39us einen 
Interrupt, aber mal ehrlich: das Ding hat 56MHz, das sind 17,Xns pro 
Instruktion, er sollte es doch wohl packen, den Interrupt zu bearbeiten 
und zwischen den Bytes (die sendet ja der UART), die LED weiter zu 
toggeln ... Oder habe ich irgendwas übersehen? Habe es auch schon 
probiert, während den Bytes den Timer auszumachen und mit dem 
TX-Interrupt vom UART1 zu arbeiten, gleiches Ergebnis. Brauche ich 
wirklich alle 39us einen Interrupt? Könnte das mit DMA (die DMX-Werte 
werden ohne CPU-Arbeit direkt vom RAM in das Senderegister kopiert) 
besser gehen? Ist das nötig? Hat das schon mal jemand gemacht?

Ideen und Kommentare sind wärmstens willkommen

von Jannis A. (jannis_)


Angehängte Dateien:

Lesenswert?

Ok, hier noch ein kleiner Nachtrag:
Auf diesem Bild sieht man, wie die LED (oberer Kanal im Oszi) während 
der ersten paar Bytes (DMX signal unten) noch toggelt, später dann aber 
nicht mehr ...

von Jannis A. (jannis_)


Lesenswert?

Okay, hat sich ziemlich erledigt, danke trotzdem an alle, die sich den 
Kopf drüber zerbrochen haben:

1. 8 Datenbits + 2 Stoppbits = 10 Bits also 40us => Falsch!
 richtig ist: 1 Startbit + 8 Datenbits + 2 Stoppbits = 11 bits, also 
44us

2. Timer-Reload nach jedem DMX-Byte vergessen. Deswegen (und wegen 1.) 
hing der immer länger in der "warte bis Senderegister leer" und konnte 
nix Anderes mehr verarbeiten.

Bin trotzdem für weitere Optimierungsvorschläge dankbar!

von Falk B. (falk)


Lesenswert?

@  Jannis A. (jannis_)

>1. UART aus, PIN auf high level, Timer-Reload auf > 100us (Mark before
>break)
>2. PIN auf low, Timer-Reload auf 176us (Break)
>3. PIN auf high, Timer-Reload auf ca 50us (Mark after Break)

Kann man so machen. Einfacher ist aber, einfach die Baudrate auf die 
Hälfte oder so zu stellen und 0x00 zu senden, damit generiert man 
automatisch ein BREAK + Pause.

>4. UART an, Null-Byte in Senderegister, Timer-Reload auf 39us

Was zum Geier machst du denn mit dem Timer immer wider? Den braucht man 
hier doch gar nicht. Das kann man alles locker mit dem UART TX Interrupt 
machen, auch wenn ich die Details des uC nicht kenne. Als Beispiel schau 
mal im Artikel Interrupt.

>5. SOLANGE warten bis Senderegister leer,

Nix Warten, Interruptgesteuert arbeiten. Dann dreht deine CPU Däumchen. 
Selbst ein AVR ist damit nur mässig ausgelastet.

>Klappt auch soweit ganz gut, nur ich will die Daten ja auch ändern, also
>UART0 (DMX sende ich auf UART1) mit ISR verbinden und immer wenn Daten
>reinkommen, diese auswerten. Klappte nicht ganz.

Wo ist das Problem? Leg deine DMX Daten in ein Array. Die 
DMX-Senderoutine liest daraus, deine whatever Empfangsroutine schreibt 
neu Daten rein. Das Array muss als volatile deklariert sein, siehe 
Artikel Interrupt.

>Interrupt, aber mal ehrlich: das Ding hat 56MHz, das sind 17,Xns pro
>Instruktion, er sollte es doch wohl packen, den Interrupt zu bearbeiten
>und zwischen den Bytes (die sendet ja der UART), die LED weiter zu
>toggeln

Eigentlich schon.

>... Oder habe ich irgendwas übersehen?

Sicherlich. Z.B, dass man in einem Timerinterrupt NICHT wartet!

> Brauche ich wirklich alle 39us einen Interrupt?

Nöö, du brauchst eigentlich gar keinen Timer. Siehe oben.

> Könnte das mit DMA (die DMX-Werte werden ohne CPU-Arbeit direkt vom RAM > in das 
Senderegister kopiert) besser gehen?

Ja.

> Ist das nötig?

Nein.

>Hat das schon mal jemand gemacht?

Sicher. Ich aber nicht direkt. Hab aber schon einige DMX-Empfänger 
gebaut, die funktionieren quasi gleich.

MfG
Falk

Ideen und Kommentare sind wärmstens willkommen

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.