Forum: Mikrocontroller und Digitale Elektronik DMX Empfang - 8051 - C


von Moving-Cam (Gast)


Lesenswert?

Hallo,

ich arbeite an unserer Hochschule derzeit an einem Projekt, bei dem mit 
Hilfe eines SiliconLabs C8051F340 Mikrocontrollers mehrere DMX-Kanäle 
empfangen und anschließend ausgewertet werden sollen (um zwei Motoren 
anzusteuern).

D.h. mit dem Mikrocontroller sollen ab einer bestimmten, einstellbaren 
DMX-Adresse sechs aufeinanderfolgende Kanäle empfangen werden, so dass 
im Endeffekt sechs Variablen mit Werten von 0-255 auf dem µC vorhanden 
sind. Die weitere Ansteuerung funktioniert bereits, lediglich der 
DMX-Empfang soll ergänzt werden (in C programmiert).

Das DMX-Protokoll ist mir bekannt, allerdings weiß ich nicht wo ich 
überhaupt anfangen soll. Vielleicht hat schon jemand einen fertigen 
C-Code um DMX mit einem 8051-Controller zu empfangen?
Es wäre nett wenn jemand das grobe Vorgehen schildern könnte oder sogar 
schon einen fertigen Code zur Hand hat.

Vielen Dank im Vorraus!

von Dietmar (Gast)


Lesenswert?

Schau mal hier 'rein.

http://www.hoelscher-hi.de/hendrik/light/ressources/AN013.pdf

Dort findest du eine Statemachine zum DMX-Empfang.

Gruß Dietmar

von Moving-Cam (Gast)


Lesenswert?

Ja, das kenn ich schon.
Wie ich das allerdings jetzt in Code umsetze (für 8051) ist mir trotzdem 
nicht wirklich klar.

von Moving-Cam (Gast)


Lesenswert?

außerdem gehts dabei ja darum, DMX zu senden...

von Dietmar (Gast)


Lesenswert?

Auf der Seite findest du Empfangen/Senden als Doku und als Sourcode 
(Zip-Files). Ist zwar für einen AVR, sollte sich aber für den 8051 
umschreiben lassen, da Beispiele in C geschrieben sind.

von Moving-Cam (Gast)


Lesenswert?

Habe das Programm von hoelscher-hi.de für den DMX-Empfang nun an den 
8051 angepasst, hierbei musste ich allerdings feststellen, dass es bei 
meinem 8051 gar kein Bit gibt, welches einen Frame Error (BREAK) 
anzeigt. Dies wird zur Erkennung des Startes aber zwingend benötigt 
oder?

Gibts eine andere Möglichkeiten, einen Break festzustellen oder hab ich 
was übersehen?

von Moving-Cam (Gast)


Lesenswert?

Jemand eine Idee?

von Der müde Joe (Gast)


Lesenswert?

Per Timer. Timer bei LOW loslaufen lassen. 88us warten. Input immer noch 
LOW? Dann ist der BREAK erkannt.

Der müde Joe.

von Moving-Cam (Gast)


Lesenswert?

D.h. sobald der UART einen Interrupt auslöst, überprüfen ob am Eingang 
LOW anliegt, wenn ja, dann einen Timer laufen lassen und nach 88us den 
Wert am Eingang erneut überprüfen. Ist dieser immer noch null, dann ist 
ein BREAK erkannt.

Ist das so korrekt oder hab ich was falsch verstanden?

von Pieter (Gast)


Lesenswert?

moin,

>>UART einen Interrupt auslöst
prüfen ob es ein Rx-Int war, wenn ja->

>>LOW anliegt, wenn ja, dann einen Timer laufen lassen
Timer mit Zeitkonstante für 88µs laden, Interrupt freigeben und 
starten...

>> und nach 88us
In der Interruptroutine, den Interrupt sperren und prufen ob Rx noch Low 
hat, ->

BREAK.

von Michael R. (mexman) Benutzerseite


Lesenswert?

Moving-Cam schrieb:
> außerdem gehts dabei ja darum, DMX zu senden...

Ja was denn nu......bisher schriebst Du immer nur "empfangen"....

> das grobe Vorgehen schildern könnte

Das kennst Du ja doch wohl und hast sogar Code dafuer bekommen

> oder sogar schon einen fertigen Code zur Hand hat

Na prima....fuer 8051 auch noch....und fuer DEINE Hardware gerade auch 
noch..... also a bisserl kannst Du Deiner Hochschule auch selber 
liefern....


Gruss

Michael

von Dietmar (Gast)


Lesenswert?

Michael Roek schrieb:
>> außerdem gehts dabei ja darum, DMX zu senden...
>
> Ja was denn nu......bisher schriebst Du immer nur "empfangen"....

Das war mein Fehler. In dem Link geht's ums senden, er will empfangen.
Für den Rest reicht der Link und eigenes Denken.

von Moving-Cam (Gast)


Lesenswert?

Ok, Danke Pieter und Joe, das mit dem Timer ist mir jetzt klar...

Aber wie muss ich denn dafür den UART initialisieren?

9bit-Modus, ist klar, dann gibts aber zwei Möglichkeiten:
1. das neunte Bit wird ignoriert,
2. oder es wird nur dann ein Interrupt erzeugt wenn das neunte Bit = 1 
ist.

Während der BREAK-Phase ist das anliegende Signal ja 22bit lang = 0, 
d.h. der zweite Fall würde keinen Sinn machen, da ja kein Interrupt 
ausgelöst werden wird, wenn das Signal dauerhaft LOW ist.

Bis jetzt hatte ich den UART mit dem zweiten Fall initialisiert, nun 
denke ich aber dass ich die erste Möglichkeit auswählen muss, oder sehe 
ich das falsch?

von Pieter (Gast)


Lesenswert?

..im Break gibt es keine Stopbits und die UART wird keinen Interrupt 
auslösen, das 9.Bit ist dafür ohne Bedeutung.
Beim F340 gibt es 2 UARTs, diese arbeiten etwas unterschiedlich, 
ansonsten kann man die "normal" initialisieren.

von Moving-Cam (Gast)


Lesenswert?

Abhängig von was soll dann der Timer gestartet werden, wenn der UART 
keinen Interrupt auslöst?

von Dietmar (Gast)


Lesenswert?

Bei jedem Byte löst der UART einen IRQ aus. In jedem IRQ startest du den 
Timer und fragst nach 88uS den Rx-Pin von deinem Controller auf low ab.
Ist der Pin dann low war es ein Break, ansonsten waren es gültige Daten.

-> Du musst also das empfangene Byte auf jedenfall zwischenspeichern bis 
die Auswertung des Break-Zustandes abgeschlossen ist.

von Dietmar (Gast)


Lesenswert?

Moving-Cam schrieb:
> 9bit-Modus, ist klar, dann gibts aber zwei Möglichkeiten:

Nix 9Bit!
8 Datenbits, kein Parity-Bit und 2 Stoppbits (8N2) Baudrate 250 kbit/s

von Moving-Cam (Gast)


Lesenswert?

Der F340 bietet aber nicht die Möglichkeit, 2 Stoppbits abzufragen, 
deshalb kann man ja das 9te Bit als erstes Stoppbit und das richtige 
Stoppbit als zweites Stoppbit sehen, dachte ich.

von Jobst M. (jobstens-de)


Lesenswert?

Dietmar schrieb:
> Bei jedem Byte löst der UART einen IRQ aus. In jedem IRQ startest du den
> Timer und fragst nach 88uS den Rx-Pin von deinem Controller auf low ab.
> Ist der Pin dann low war es ein Break, ansonsten waren es gültige Daten.

Nein 1: Der UART löst erst nach Ende eines Bytes einen IRQ aus. Wie viel 
Zeit von dort noch bis zum Ende einer möglichen Break-Kondition vergeht, 
wird man wohl durch probieren herausfinden müssen.

Nein 2: Alle machen den Fehler, nach 88µs nachsehen zu wollen, ob low 
anliegt. Es muß die ganze Zeit low anliegen! Zumindest muß man alle 4µs 
nachsehen.

22bit entsprechen 2 Bytes (1 Startbit, 8 Datenbits, 2 Stopbits = 11Bits 
je Byte)

Man sollte also ehr drauf schauen, ob die Stopbits in der Zeit 36-44µs 
vorhanden sind. Ist dem nicht so, ist es eine Break-Kondition und das 
empfangene Byte sind keine Daten.

Wenn die UART tatsächlich keine Auswertung eines fehlenden Stopbits 
zulässt, würde ich vermutlich so vorgehen:

Init:
Rx an einen INT-Pin anschliessen.
INT auf fallende Flanke.
TimerReload auf 4µs einstellen.
ExtIRQ erlauben.
IRQ erlauben
RET

ExtInt:
ExtIRQ verbieten
TimerIRQ erlauben
Timer mit 6µs vorladen
Zähler=0
RET

TimerInt:
Zähler++
Wenn 0<Zähler<9 dann Byte mitschreiben
Wenn 8<Zähler<11 dann Bits merken

Wenn Zähler=10
{ Wenn Bits 2x 0 und Byte = 0x00 dann -> Break
  Wenn Bits 2x 0 und Byte != 0x00 dann -> Error
  Wenn Bits 2x 1 dann
  { Byte irgendwo notieren
    Kanal++
    -> EndTransmission
  }
  Wenn Bit 1 <> Bit 2 dann Error
}
RET

Break:
 Kanal=0
EndTransmission:
 TimerIRQ verbieten
 ExtIRQ erlauben
 RET



Gruß

Jobst

von Falk B. (falk)


Lesenswert?

Oder einfach einen gescheiten u nehmen, der BREAK direkt erkennen kann, 
das können sogar die ollen PICs ;-).

von Dietmar (Gast)


Lesenswert?

Und wenn man den uC nicht tauschen kann, externen Uart anbinden.

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.