DMX512-Transmitter

Here you see 2 DMX512-Transmitter:The first is using the Hardware-USART and Bascom Highlevel commands. At the second I build the DMX-Signal Bit for Bit. The Timing is calculatet for 8 MHz, you can not use an different Resonator.

DMX512-Transmitter with Bascom-Basic

The USART an AT-Mega have everything you need to send DMX signals. However, we must navigate around a problem with arrays > 255. Therefore i divided the 512 channels to 3 arrays. If not all channels need to be sent, you can simply leave out the unnecessary. We also have to build the Reset and the Zerobyte.

Sourcecode

$regfile = "m8def.dat"
$crystal = 16000000
$baud = 250000

Config Com1 = Dummy , Synchrone = 0 , Parity = None , Stopbits = 2 , Databits = 8 , Clockpol = 1

Dim Puffer1(255) As Byte
Dim Puffer2(255) As Byte
Dim Puffer3(2) As Byte
Dim Null_byte(1) As Byte

Usart_tx Alias Portd.1
Config Usart_tx = Output

Do
Ucsrb.txen = 0                                          'Usart ausschalten
Usart_tx = 0                                            'Reset abfallende Flanke
Waitus 200                                              'minimale Länge des Resets
Usart_tx = 1                                            'Reset aufsteigende Flanke
Ucsrb.txen = 1                                          'Usart einschalten
Waitus 16                                               'MARK zw. RESET und Startbyte min. 8us
Printbin Null_byte(1) ; 1 ; Puffer1(1) ; 255                    'jetzt die Daten
Printbin Puffer2(1) ; 255
Printbin Puffer3(1) ; 2
'Hier dein genialer Code rein...
Loop

DMX512-Transmitter with Assemblercode

The Signal was built Bit for Bit. The Array Puffer() contents all values of the 512 Channels. The complete routine lies in an Interrupt and send all 512 Channels.

Regard! The sending with the USART to the microcontroller is more comfortable and easier to use in most cases. But when you want to tune all parameters of the DMX signal, you can to this by inserting loops with NOPs that are set longer or shorter.

Sourcecode

'###############################################################################
'#
'#    DMX 512 Sender 1.2c
'#
'#    (c) Günter Gerold
'#
'#    DMX 512 Signale senden mit Bascom-Basic
'#    Das Timing stimmt nur bei 8 MHz Quarz andere Quarze erfordern eine
'#    Neuberechnung des Timings!
'###############################################################################

$regfile = "m8def.dat"
$crystal = 8000000
'Der Timer0 löst einen Interrupt aus und sendet dann das DMX-Signal
On Timer0 Ontimer0
Timsk.toie0 = 1
Tccr0 = &B00000101
'Der Pin D7 sendet das DMX-Signal
Config Portd.7 = Output
Dmxout Alias Portd.7

'hält den Wert des aktuellen Kanals in der Schleife
Dim Temp As Word
'der aktuelle Kanal in der Schleife
Dim Kanal As Word
'in das Array müssen die Werte der Kanäle reingeschrieben werden
Dim Puffer(513) As Byte

Enable Interrupts

Do
'Hier muß noch dein genialer Code rein!
'Puffer(2) = 123 setzt z.B. DMX-Kanal 2 auf den Wert 123
Loop


'###############################################################################
'#
'#   Das ist der eigentliche DMX512 Generator. Das Einfügen oder Weglassen
'#   selbst von scheinbar unnötigen NOPs führt zu Timingproblemen.
'#
'###############################################################################

Ontimer0:
Timer0 = 70
Dmxout = 1
$asm
.def Tmp1 = R17                                             'Marker
.def Tmp2 = R18
            ldi  Tmp1, $5
Make_loop1:
            dec  Tmp1
            brne Make_loop1
            nop
            nop
$end Asm
For Kanal = 0 To 512                                        '8   'Anzahl der Kanäle
   Temp = Puffer(kanal)                                     '20
   $asm
   .def Temp1 = R17
   .def Temp2 = R18
   .def Txbyte = R19
   Putchar:
      LDS Txbyte, {Temp}                                    '2
      LDI Temp1 , 9                                         '1
      COM Txbyte                                            '1
      SEC                                                   '1
   Putchar0:
      BRCC Putchar1                                         '1 oder 2
      nop                                                   '1
      CBI Portd,Pd7                                         '2
      RJMP putchar2                                         '2
   Putchar1:
      SBI Portd,Pd7                                         '2
      NOP                                                   '1
      nop                                                   '1
   Putchar2:
      LDI Temp2 , $7                                        '1
   Sd_loop0:
      DEC Temp2                                             '1
      BRNE Sd_loop0

      nop
      LSR Txbyte                                            '1
      DEC Temp1                                             '1
      BRNE putchar0                                         '1 oder 2
   $end Asm
   nop
   nop
   nop
   Dmxout = 1                                               '2 genauso schnell wie SBI PORTD,PD7 in Assembler
   $asm
   .def Tmp1 = R17
   .def Tmp2 = R18
   ldi  Tmp1, $1                                            '1
   Make_loop0:                                              '2 Stoppbits
      dec  Tmp1                                             '1
      brne Make_loop0                                       '1 oder 2
   $end Asm
Next Kanal                                                  '10
   $asm
   .def Tmp1 = R17
   .def Tmp2 = R18
   ldi  Tmp1, $7
   Make_loop3:                                              'zusätzlich für Kanal 512
      dec  Tmp1
      brne Make_loop3
   $end Asm
Dmxout = 0
Waitus 88
Dmxout = 1
Return