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!
Schau mal hier 'rein. http://www.hoelscher-hi.de/hendrik/light/ressources/AN013.pdf Dort findest du eine Statemachine zum DMX-Empfang. Gruß Dietmar
Ja, das kenn ich schon. Wie ich das allerdings jetzt in Code umsetze (für 8051) ist mir trotzdem nicht wirklich klar.
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.
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?
Per Timer. Timer bei LOW loslaufen lassen. 88us warten. Input immer noch LOW? Dann ist der BREAK erkannt. Der müde Joe.
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?
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.
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
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.
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?
..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.
Abhängig von was soll dann der Timer gestartet werden, wenn der UART keinen Interrupt auslöst?
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.
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
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.
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
Oder einfach einen gescheiten u nehmen, der BREAK direkt erkennen kann, das können sogar die ollen PICs ;-).
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.