Forum: Mikrocontroller und Digitale Elektronik DMX Senderoutine in Assambler


von Der Bastler (Gast)


Lesenswert?

Guten abend liebe Leute,

nach langem suchen habe ich nun doch entschieden zufragen.
Ich suche eine DMX Senderoutine in Assambler hatte da mal etwas gehabt 
aber verloren und wenn ich in der Suche dmx eingab kamen zwar 
1000ergebnisse aber filtern wir die Empfänger und die Codeschnipsel in C 
raus bleibt nich mehr viel übrig.

Möchte das Fahrrad nicht neu erfinden hat einer ein Codeschnipsel mit 
dem ich die Kanalbytes die im Ram liegen über UART raus senden kann?
Brauch das in Assembler

von Falk B. (falk)


Lesenswert?

Für welchen Prozessor?

von Der Bastler (Gast)


Lesenswert?

Ich denke für ein Atmega8151 (wird noch gekauft) aber mit dem kenn ich 
mich am besten aus

von Falk B. (falk)


Lesenswert?

@ Der Bastler (Gast)

>Ich denke für ein Atmega8151 (wird noch gekauft)

Den gibt es nicht. Es gibt ATmega8515 und ATmega8535.

von Der Bastler (Gast)


Lesenswert?

Ups vertippt atmega8515

von Weingut P. (weinbauer)


Lesenswert?

ist doch weiter kein Problem, erstmal das
Breake-Signal und dann die Bytes nacheinander ins
Senderegister schreiben, dazwischen entweder warten bis Senderegister 
leer
oder den TXC-Interrupt nehmen um das nächste Byte zu schreiben.

von der bastler (Gast)


Lesenswert?

ist es wirklich so einfach? ich generiere 22mal ne 0 als break 88ųSek 
dann 8ųsek 2mal ne 1 mark after break dann mein startbit eine 0 dann 
mein kanalbyte das stopbit 8ųsek lang und dann wieder n startbit?

mark after break is das 8ųsek oder 4ųsek lang?

frameformat ist 8bit?

von Wegstaben V. (wegstabenverbuchsler)


Lesenswert?

schreibst du deine Programme in ähnlicher Sprache wie deine Beiträge? 
Meldet da der Compiler keine Fehler?

Übrigens heißt das Zeugs "Assembler" und nicht "Assambler"

von Falk B. (falk)


Lesenswert?

@ der bastler (Gast)

>ist es wirklich so einfach?

Eigentlich schon.

>ich generiere 22mal ne 0 als break 88ųSek
>dann 8ųsek 2mal ne 1 mark after break dann mein startbit eine 0 dann
>mein kanalbyte das stopbit 8ųsek lang und dann wieder n startbit?

Wenn du so programmierst wie du hier schreibst wird das eher ehtwas 
schwierig. Du weißt anscheinend nicht, wei ein UART funktioniert.

>mark after break is das 8ųsek oder 4ųsek lang?

Das ist vollkommen nebensächlich. Mach es irgendwa zwischen 10-100us und 
gut.

>frameformat ist 8bit?

Schon mal versucht, eine Spezifikation von DMX512 zu lesen?

http://www.mikrocontroller.net/articles/Linksammlung#DMX512_2

von Andreas L. (andi84)


Lesenswert?

Moin,

warum in Assembler?
So eine wahnsinnsperformance braucht man für DMX nicht, dass sich das 
lohnen würde.
Grundsätzlich gibt es zwei gebräuchliche Wege, DMX zu senden:

1) Man nutzt einen UART und einen Timer, wobei der Timer für MAB und 
Break sorgt
2) Man nutzt nur den UART und verändert die Baudrate passend, um Break 
und MAB zu erzeugen

Beides schon gesehen. Selber nutze ich meist die Variante mit Timer und 
UART.

Ich hänge da mal den C-Code für DMX-Tx an, den ich irgendwann mal 
geschrieben habe. Läuft so wie er da steht mit einem 16MHz-Quarz, für 
andere Frequenzen sind die Timings entsprechend anzupassen.
1
#include <inttypes.h>
2
#include <avr/io.h>
3
#include <avr/interrupt.h>
4
#include <util/delay.h>
5
#define F_OSC 16000000
6
#define USART_BAUD(F_OSC) ((F_OSC)/((250)*16)-1)
7
8
//Einstellungen BREAK-Dauer (min 88us, 125us empfohlen (und verwendet), kein oberer Grenzwert)
9
#define BRK_TCNT 6
10
#define BRK_PSCB 2
11
12
//Einstellungen MAB-Dauer (min 8us, max 1s, verwendet: 32us)
13
#define MAB_TCNT 192
14
#define MAB_PSCB 2
15
16
//Anzahl DMX-Kan�le
17
#define DMX_CHAC 64
18
19
volatile uint8_t dmx_data[DMX_CHAC];
20
volatile uint8_t dmx_ptr=0;
21
volatile uint8_t dmx_tmrfunc=0;
22
23
SIGNAL(SIG_OVERFLOW0)
24
  {
25
  if (dmx_tmrfunc==0) //BREAK Ende, MAB start
26
    {
27
    TCCR0=(TCCR0&0xf8)|MAB_PSCB;
28
    TCNT0=MAB_TCNT;
29
    dmx_tmrfunc=1;
30
    PORTD|=(1<<1);//TxD High
31
  }else //MAB Ende
32
    {
33
    dmx_ptr=0;
34
    UCSRB|=(1<<TXEN)|(1<<TXCIE);//USART wieder einschalten
35
    TIMSK&=~(1<<TOIE0);
36
    UDR=0;
37
  }
38
}
39
40
SIGNAL(SIG_UART_TRANS)
41
  {
42
  if (dmx_ptr==DMX_CHAC)
43
    {
44
    TIFR|=(1<<TOV0);
45
    UCSRB&=~((1<<TXEN)|(1<<TXCIE));//USART ausschalten
46
    TCCR0=(TCCR0&0xf8)|BRK_PSCB;
47
    TCNT0=BRK_TCNT;
48
    dmx_tmrfunc=0; //BREAK wird erzeugt
49
    TIMSK|=(1<<TOIE0);
50
    UCSRB&=~(1<<TXCIE);
51
    PORTD&=~(1<<1); //TxD Low (wird �bernommen, sobald USART fertig ist)
52
  }else
53
    UDR=dmx_data[dmx_ptr++];
54
}
55
void startdmx(void)
56
  {
57
  TIFR|=(1<<TOV0);//Clear old Interrupt flag
58
  TCCR0=(TCCR0&0xf8)|BRK_PSCB;
59
  TCNT0=BRK_TCNT;
60
  dmx_tmrfunc=0; //BREAK wird erzeugt
61
  TIMSK|=(1<<TOIE0); //enable tov0 interrupt
62
  PORTD&=~(1<<1); //TxD Low
63
}

von Jürgen B. (hicom)


Lesenswert?

Schau hier mal unter AN013: DMX-Transmission mit AVRs:

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

Gruß
Jürgen

von Der Bastler (Gast)


Angehängte Dateien:

Lesenswert?

So schaut mein Programm nun aus ich habe den TXD ausgang nach dieser 
Abbildung mit der DMX Buchste verschaltet:
http://www.mintiworld.de/wiki/images/9/96/DMXout.gif
Das Programm soll auf channel 1 und 2 jeweils eine 255 senden und 256 
Kanäle senden.


Abundzu erkennt das Gerät(eine LED Matrix) ein DMX Signal kann dies 
jedoch anscheinend nicht bearbeitet werden kann, manchmal leuten alle 
Lichter manchmal Garkeins.

komisch ist auch, das der TXD Pin im Leerlauf 0.01V Spannung ausgibt, 
ist das normal?

Spannung:
DMX- = 3.11V
DMX+ = 1.92V
DI MCU TXD = 3.24V

von Falk B. (falk)


Lesenswert?

@Der Bastler (Gast)

>    The_Game.asm (2 KB, 0 Downloads) | Codeansicht

Naja. Da sind noch einige Bugs drin. Und die Formatierung ist nichtg 
gut, was Bugs LIEBEN!

Strukturierte Programmierung auf Mikrocontrollern

>http://www.mintiworld.de/wiki/images/9/96/DMXout.gif

Ist OK.

>Das Programm soll auf channel 1 und 2 jeweils eine 255 senden und 256
>Kanäle senden.

Bissel wenig. Aber für den Anfang OK.

>Abundzu erkennt das Gerät(eine LED Matrix) ein DMX Signal kann dies
>jedoch anscheinend nicht bearbeitet werden kann, manchmal leuten alle
>Lichter manchmal Garkeins.

Was nicht verwunderlich ist.

>komisch ist auch, das der TXD Pin im Leerlauf 0.01V Spannung ausgibt,
>ist das normal?

Nein. TXD liegt im Leerlauf auf VCC.

>Spannung:
>DMX- = 3.11V
>DMX+ = 1.92V
>DI MCU TXD = 3.24V

Wie hast du gemessen? Mit dem Multimeter? Das geht nur, wenn keinerlei 
Daten gesendet werden. Dann muss DMX+ aber nache VCC und DMX- nahe GND 
liegen. Ist bei dir nicht der Fall, also stimmt was nicht!

von spess53 (Gast)


Lesenswert?

Hi

>Abundzu erkennt das Gerät(eine LED Matrix) ein DMX Signal kann dies
>jedoch anscheinend nicht bearbeitet werden kann, manchmal leuten alle
>Lichter manchmal Garkeins.

Wundert mich nicht.

>  sbis    UCSRA,UDRE    <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
>  rjmp    SendDMX
>  ldi     temp, HIGH(B_UBRR_VAL)
>  out     UBRRH, temp
>  ldi     temp, LOW(B_UBRR_VAL)
>  out     UBRRL, temp

Vor der Umschaltung der Baudrate solltest du TXC und nicht UDRE testen. 
UDRE sagt nur, das der Sendepuffer ein Byte aufnehmen kann, aber 
nicht, das die USART mit der Übertragung fertig ist. Damit kann die 
Baudrateumschaltung u.U. noch während der laufenden Übertragung 
stattfinden.

MfG Spess

von Falk B. (falk)


Angehängte Dateien:

Lesenswert?

Probier mal das hier.

von Der Bastler (Gast)


Lesenswert?

Danke Falk ich werde es mal testen und nochmal messen, die Messungen 
wurden während des sendens gemacht.
Nun die Formatierung in Atmelstudio schaut eigentlich ganz anderst aus, 
glaubt nicht, dass ich so ein mist gemacht hab:

rjmp    SendDMX  ;Channel durch UART scheuchen    ;Warten bis Buffer 
leer ist

@spess53 danke für die Aufklärung das wollte ich auch erreichen bevor 
ich die Baudrate umschalt.

Also mit deinem Programm Falk bin ich soweit, dass die Verbindung 
nichtmehr abbricht und ein Eckpunkt der Matrix dauerhaft leuchtet kann 
nun nicht sagen ob das der Erste oder der Letzte Channel ist.

Atmelstudio zeigt eine Warnung:
1 .cesg .db misalignment - padding zero byte

TXD Zeigt im Leerlauf nun 5V warum war das bei mir nicht der fall?

von Falk B. (falk)


Lesenswert?

@Der Bastler (Gast)

>Danke Falk ich werde es mal testen und nochmal messen, die Messungen
>wurden während des sendens gemacht.

aha, warum schreibst du dann was von Leerlauf? Was ist denn für dich 
Leerlauf?

>Nun die Formatierung in Atmelstudio schaut eigentlich ganz anderst aus,
>glaubt nicht, dass ich so ein mist gemacht hab:

Indirekt schon.

http://www.mikrocontroller.net/articles/Strukturierte_Programmierung_auf_Mikrocontrollern#Formatierung_des_Quelltextes

"Tabulatoren als Leerzeichen einfügen lassen: Das können die Editoren 
heute allein. Der Vorteil ist, dass der Quelltext danach immer gleich 
aussieht, und nicht auf einem anderen Editor mit anderer 
Tabulatoreinstellung verschoben aussieht. "

>Also mit deinem Programm Falk bin ich soweit, dass die Verbindung
>nichtmehr abbricht und ein Eckpunkt der Matrix dauerhaft leuchtet kann
>nun nicht sagen ob das der Erste oder der Letzte Channel ist.

>Atmelstudio zeigt eine Warnung:
>1 .cesg .db misalignment - padding zero byte

jaja, ist unkritisch

>TXD Zeigt im Leerlauf nun 5V warum war das bei mir nicht der fall?

Was verstehst du unter Leerlauf? Dein Programm läuft immer, also gibt es 
keinen Leerlauf.

von Der Bastler (Gast)


Lesenswert?

Leerlauf den Pin zwischen TXD und dem SN75176 entfernt die 
Leerlaufspannung am TXD Pin.

während ich die DMX eingänge gemessen habe, als dieser Pin wieder 
verbunden war also während des sendens.

Nun nachdem ich das Gerät neustartete erkennt es zwar, dass DMX Signale 
anliegen allerdings leuchtet keine der LEDs.

von Falk B. (falk)


Lesenswert?

@ Der Bastler (Gast)

>Leerlauf den Pin zwischen TXD und dem SN75176 entfernt die
>Leerlaufspannung am TXD Pin.

Auch dann ist dort kein Leerlauf! Das Programm läuft!

>während ich die DMX eingänge gemessen habe, als dieser Pin wieder
>verbunden war also während des sendens.

Ebenso!

>Nun nachdem ich das Gerät neustartete erkennt es zwar, dass DMX Signale
>anliegen allerdings leuchtet keine der LEDs.

Naja, ein WENIG Eigeninitialive und Mitdenken wäre schon nicht schlecht. 
Z.B, indem du die Tabelle mit den DMX_Startwerte mal vergrößerst! Ach 
ja, der erste Wert dort muss 0 sein, das ist das DMX-Startbyte. Wenn das 
nicht Null ist, können einige Geräte das als ungültigen DMX-Datenstrom 
werten und die Datenaufnahme verweigern.

von Der Bastler (Gast)


Lesenswert?

Selbes Ergebnis nix leuchtet und der 1. Wert in der Tabelle ist 0 habe 
sie auf weitere Stellen erweitert.

Wo kommen in dem Programm die Werte aus dem Ram ins Spiel?

von Der Bastler (Gast)


Lesenswert?

bzw warum verwendest du den z Pointer als Feiger im Flash um dannach auf 
den ram zu zeigen?

von Der Bastler (Gast)


Lesenswert?

Ah verstehe, ich brauch ein bisschen.
Sehe ich das richtig du schreibst die Werte aus dem flash in den RAM um 
sie dann aus dem Ram in die UART zu schicken?

von Falk B. (falk)


Lesenswert?

Genau
Bei festen Daten könnte man auch direkt aus dem Flash lesen und auf den 
UART schicken, ist hier eine Geschmacksfrage. Aber meistens will man ja 
die DMX-Daten verändern, also doch wieder RAM.

von Der Bastler (Gast)


Lesenswert?

gut das Programm ist recht simpel habe es verstanden wirklich 
erfolgreich ist das noch nicht, wenn ich das Signal der Avr abziehe 
entstehen manchmal interessante Muster, wenn ich es wieder dran stecke 
leuchtet eine Ecke.
Wie könnte ich denn das Signal verfolgen ein Oszi hab ich leider nicht
Sind Störungen von aussen möglich? meine Schaltung ist auf einem 
Steckboard allerdings eins von der guten Sorte.

von Der Bastler (Gast)


Lesenswert?

Also ich vermute nun einfach es liegt an meinem Steckboard, dass die 
Schaltung nicht funktioniert, werde mal ne Platiene herstellen und das 
drauf löten.

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.