PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : DMX Sender mit 89C51



BriteLite
18.06.2010, 10:24
Moin Leute,
ich stehe hier mal wieder vor einem für mich wohl unlösbarem Problem.
Ich möchte einen Led Balken (252 Led's / 13 DMX Kanäle) mit einem 89C51 per DMX ansteuern.
Die DMX Werte kommen später aus einem vorhandenem LED Scheinwerfer der als Master definiert ist. Er gibt also an seiner DMX Buchse die Werte der Farben rot,grün und blau raus. Dies auf Kanal 1-3. Mein Balken versteht darauf nur Bahnhof. Er braucht auf Kanal 2-4 die Farbwerte.
Meine Idee ist also DMX Werte von Scheinwerfer in 89c51 ziehen, wenn erhalten nach Kanal 2-4 umsortieren und ausgeben, dann Spielchen von vorne.
Leider scheitere ich schon bei dem Versuch meinem Balken zunächst mal feste DMX Werte zu senden.:(
Ich hoffe auf eure Hilfe bzw. auf denjenigen der mir den Fehler unter die Nase reibt.
Mein Balken gibt zwar die richtigen Farben wieder aber er flackert! Für mich ein Zeichen das mit der DMX Senderei noch irgendein Timing Problem besteht.
Oszi ist nicht vorhanden bzw. zu alt DMX ordentlich darzustellen.
Ich habe aber einen DMX Tester. Er zeigt mir den Break mit 91µs und den Mark mit 10µs an. Zyklus mit 140µs. Auch die Verlangsamung mittels ausgeklammerten Part löst nicht das Problem. Seltsamerweise wird der Frame vom Tester mit !! 1µs !! angezeigt?? Das kann ich doch aber nicht ändern, oder?
Bitte gebt mir keine tollen Tipps wo ich mal nachschauen sollte o.ä.
Auch keine anderen µP's vorschlagen. Es geht nur mit den 89c51/52 und 89c1051/2051 und Assembler. Anders vertehe ich nicht und andere µP kann ich auch nicht programmieren.Ich möchte es auch mit der seriellen Schnittstelle lösen.
Also Hiiiiiilfe.
Hier das Programm:

INCLUDE 89C51.mc
;Quarz 8Mhz
;-----------------------------
INI:
MOV scon,#$80 ;UART 9bit 8Mhz/32 = 250 kBaud (Betriebsart 2)
MOV pcon,#$80 ;Teiler / 2 Ein ! (SMOD EIN= OSZ:2:16) sonst (Osz:2:2:16)
MOV sbuf,#0
MOV R4,#26
SETB tb8 ;UART 2. Stoppbit!
SETB ti
MOV $30,#0 ;Kanal 1 DMX Wert 0 (Dimmer)
MOV $31,#100 ;Kanal 2 DMX Wert 100 (Rot)
MOV $32,#0 ;Kanal 2 DMX Wert 0 (Grün)
MOV $33,#255 ;Kanal 2 DMX Wert 255 (Blau)

;************************************************* ********************************
; DMX SENDEROUTINE
;************************************************* ********************************
; Break erzeugen 90 µs

BREAK:
CLR ti
MOV R7,#30 ;nachfolgende Befehle brauchen ebenfalls 45µs, daher hier nur 30
CLR p3.1 ;TXD auf Low

BR_WAIT:
DJNZ R7,BR_WAIT
SETB p3.1 ;TXD auf High
;************************************************* ********************************
;8 µs MARK durch NOP 2x
NOP ;nachfolgende Befehle brauchen 7,5µs daher nur 2 Nop's
NOP
;************************************************* ********************************
MOV sbuf,#0 ;0 Byte senden
ACALL SEND_WAIT
;************************************************* ********************************
MOV R0,#$30 ;Zeiger auf DMX puffer
MOV R7,#4 ;Anzahl der zu übertragenden DMX Pakete

SEND:
MOV sbuf,@R0 ;DMX wert aus Puffer senden
INC R0
ACALL SEND_WAIT
DJNZ R7,SEND ;Alle Kanäle gesendet?
SETB p3.1 ;TXD auf High

;SEND_2: ;zur Zeit nicht aktiv
;DJNZ R5,SEND_2
;DJNZ R4,SEND_2
;MOV R4,#26
JMP BREAK

SEND_WAIT:
JNB ti,SEND_WAIT ;warte auf Übertragung fertig
CLR ti ;lösche Transmit Bit
RET

Übrigens.. ganz so falsch kann das Programm nicht sein.
Setze ich DMX Werte für den Scheinwerfer ein und sende es mit dieser Routine, macht der Spot alles korrekt. Er ist aber werkseitig so programmiert das er die zuletzt empfangenen Werte auch bei DMX Ausfall hält.
Der Balken hat das nicht. Kein DMX = Alles dunkel.

Andy8051
13.06.2011, 20:06
ich weiss ja net ob das Thema noch aktuell ist.
Ich habe mich letztens auch mit DMX beschäftigt und möchte hier mal eine kleine
Routine zum Besten geben, um DMX zu senden.
Der Vorteil: es wird kein UART ver(sch)wendet, dieser kann z.B. für MIDI verwendet werden, so wie ich es gemacht habe :)
Verwendet habe ich einen AT89C4051 mit 12MHz-Quarz, Takt also 1uS
Hier ein Auszug - die DMX-Senderoutine:
(Zahlen hinter dem Semikolon sind Takt-Zyklen)


;***** DMX-Senderoutine *****
DMX_out:
;Break erzeugen (mind.88uS max.1Sek)
MOV R0,#DMX_String
MOV R7,#12 ;Anzahl Kanäle
MOV A,#50 ;1 90uS
CLR dmx_port ;1
DJNZ acc,$ ;2
;Mark erzeugen (8 uS)
SETB C ;1
MOV dmx_port,C ;2
MOV A,#0 ;1 Start-Byte immer 0
NOP ;1
NOP ;1
NOP ;1
NOP ;1
LCALL send_byte ;2
NOP
NOP
NOP
NOP
NOP
NOP
DMX_out10: MOV A,@R0 ;1
INC R0 ;1
LCALL send_byte ;2
DJNZ R7,DMX_out10 ;2
RET

 
 
;***** DMX-Byte (in A) senden *****
;(Zeit-optimiert)
;----------------------------------
send_byte: CLR C ;1
MOV dmx_port,C ;2
RRC A ;1
NOP ;1
;bit 0
MOV dmx_port,C ;2
RRC A ;1
NOP ;1
;bit 1
MOV dmx_port,C ;2
RRC A ;1
NOP ;1
;bit 2
MOV dmx_port,C ;2
RRC A ;1
NOP ;1
;bit 3
MOV dmx_port,C ;2
RRC A ;1
NOP ;1
;bit 4
MOV dmx_port,C ;2
RRC A ;1
NOP ;1
;bit 5
MOV dmx_port,C ;2
RRC A ;1
NOP ;1
;bit 6
MOV dmx_port,C ;2
RRC A ;1
NOP ;1
;bit 7
MOV dmx_port,C ;2
;2 Stop-Bits (8 uS)
SETB C ;1
NOP ;1
MOV dmx_port,C ;2
;NOP ;1
;NOP ;1
;NOP ;1 der Rest erzeugt die 2 Stop-Bits ;-)
RET ;2