Ich hab ein paar DMX Sourcen hier.
Beispielsweise mal eine kleine für einen ATMEGA8 für ein Stroboskop.
Ist allerdings in ASM. Für die Registerinstellungen sollte es aber reichen.
Soweit ich mich erinnern kann lief das Teil mit 8MHz.
Code:
.include "m8def.inc"


;***** pin definitions

.equ	dmx_in		=PD0			;receive pin is PD0 (RXD)
;.equ	zero_crossing_pin=PD2			;interrupt 0


;***** constants

.equ	channels	=1
.equ	channels_all	=1

.equ	spi_start_byte	=0xfa
.equ	spi_stop_byte	=0xff
.equ	minvalue=0x09		;Min value of valid DMX Datas -> Switches Stroboscope off
.equ	maxvalue=0xF7		;Max value of valid DMX Datas -> generates optional Single Flash impuls

;***** global register variables

; ZL, ZH, XL and XH used for memory-comtrolling
; R0 used for memory-operations (lpm)
; R1 used as NULL-register


.def	tempL		=R24			;temporary storage register
.def	tempH		=R25			;
.def	temp		=R17			;

.def	dmx_byte	=R6			;value of got byte
.def	dmx_count_in	=R19			;counter for valid dmx-byte
.def	dmx_countL	=R20			;counter for incomming dmx-byte
.def	dmx_countH	=R21			;

.def 	dmx_status	=R16			;status of incomming data
						;0x00 -> ok
						;0x01 -> wait for reset
						;0x02 -> startbyte
						;0xff -> dmx fail

.def 	dmx_adrL	=R4			;set start adress
.def 	dmx_adrH	=R5			;

.def	shadc		=R7			;actual adc value	
.def	status		=R18			;Bit0=single Shot
.def	actvalue	=R9			;actuell dmx value

;.def	currentL	=R22			;data
;.def	currentH	=R23			;data

.def	led_count	=R10			;counter

.def	shdmxbyte	=R8
;.def	spi_count	=R28	

.def	timer_matchL	=R11
.def	timer_matchH	=R12
.def	shUCSRA			=R13

;****set interrupt-routines

.org 0	
	rjmp 	reset			;general reset
	reti 					;ext. int.0
	reti					;ext. int.1
	reti					;timer2 copare match
	rjmp	stopflash		;timer2 overflow
	reti					;timer 1 capture event
	rjmp	compare			;timer1 compare match A
	reti					;timer1 compare match B
	reti					;timer1 overflow interrupt
	reti					;timer0 overflow interrupt
	reti					;spi complete
	rjmp 	get_byte		;uart rx complete
	reti					;uart data register empty
	reti					;uart tx complete
	rjmp	adcready		;adc conversion complete
	reti					;eeprom ready
	reti					;analog comperator
	reti					;Two-wire serial interface
	reti					;Store Programm Memory ready

reset:

cli

;***** set stackpointer
		ldi	tempL, low(RAMEND)
		ldi tempH, high(RAMEND)
		out	SPL,tempL
		out SPH,tempH 

;***** initial adc
		ldi	tempL,0b11100101	;adc init ADC ein, Port 5 Interne Referenz
		out ADMUX,tempL
		ldi tempL,0b11011111	;ADC start Conversation CK/128 Interrupt enabled
		out	ADCSRA,tempL	

;***** initial portd
		ldi 	tempL,0b11111100	;Pull up resistors on PD 4..7 high Port 2+3 high
		out	PORTD,tempL
		ldi 	tempL,0b00001100	;init port d high Adress
		out	DDRD,tempL

;***** initial portb
		ldi 	tempL,0b00000000	;init port b low Adress
		out	DDRB,tempL
		ldi 	tempL,0b00111111	;Pull up resistors on	
		out	PORTB,tempL

;***** initial portc
		ldi 	tempL,0b00000000	;init port c Bit 0 Signal out, Bit 1 DMXLED
		out	DDRC,tempL
		ldi tempL,0b00000000
		out	PORTC,tempL

;***** initial var
		ldi	tempL,0x00		;set R1 to NULL
		mov	R1,tempL		;

		 
;***** initial timer 0 - not used
;		ldi 	tempL,0b00000001	;set timer0 to ck
;		out 	TCCR0,tempL		;
				

;***** initial timer 1
		ldi 	tempL,0b00000000	;set timer1 to normal function
		out		TCCR1A,tempL
		ldi		tempL,0b00000101	;set timer 1 to clk/1024
		out 	TCCR1B,tempL
		ldi		tempL,0x00			;set timer value to 0
		out		TCNT1H,templ
		out		TCNT1L,templ
		LDI		templ,0xFF
		out		OCR1AH,templ		;set copare match A register to FF hex
		out		OCR1AL,templ
		ldi		templ,0b00000000	;disable Timer 1 A compare match Interrupt
		out		timsk,templ
	

;***** initial timer 2
		ldi 	tempL,0b00000011	;set timer1 to normal function, clk/32
		out		TCCR2,tempL
		ldi		tempL,0x00			;set timer value to 0
		out		TCNT2,templ
		ldi		templ,0b00000000	;disable Timer 2 overflow Interrupt
		out		timsk,templ

;***** initial var
		rcall 	start_adress		;get start adress

		ldi	dmx_countL,0x00		;reset counter
		ldi	dmx_countH,0x00		;
		ldi dmx_count_in,0x00	;


;***** initial UART
		ldi	tempL,0x01		;set UART to 250 kbaud @ 8mhz
		clr tempH
		out	UBRRL,tempL		;
		out UBRRH,temph

		ldi 	tempL,0b00000000	;set UART to 8 bit 
		out 	UCR,tempL		;

		sbi 	UCSRB,RXEN		;enable UART receiver

		ldi 	dmx_status,0x01		;set dmx-status byte to 'wait for reset'
		in	dmx_Byte,UDR		;clear UART receive interrupt flag
 		cbi	UCSRA,FE		;clear frame error flag
		sbi 	UCSRB,RXCIE		;enable UART receive interrupt


;***** start working...

		sei				;enable global interrupt

main:	
		rcall start_adress
		clr temp
		mov templ,dmx_adrL
		mov temph,dmx_adrH
		CLC
		cp temp,templ
		cpc	temp,temph
		brne main2
		rcall adcmode
main2:	rjmp main
				
	
		
adcmode:
		mov temp,shadc
		LDI zl,low(timetable*2)		;Timerwerte aus Tabelle auslesen
		LDI zh,high(timetable*2)
		ADD zl,temp
		ADC zh,R1
		ADD zl,temp
		ADC zh,R1
		LPM R0,Z+
		MOV timer_matchH,R0			;
		LPM R0,Z
		MOV timer_matchL,R0
		OUT OCR1AH,timer_matchH
		OUT OCR1AL,timer_matchL
		IN	temp,TIMSK
		ORI temp,0b01010000			;Timer 1 Compare Interrupt einschalten
		OUT TIMSK,temp
		ret





;***************************************************************************
;*
;* initiate a flash pulse
;*
;***************************************************************************
flash:
		push temp
		in temp,SREG
		push temp
		cbi portd,3				;start Flash puls
		LDI temp,0b11011111		;Start ADC
		OUT ADCSRA,temp
		LDI temp,0x00
		out TCNT1H,temp			;Clear Timer 1
		out TCNT1L,temp
		out TCNT2,temp			;Counter 2 to Startvalue
		LDI temp,0b01010000		;delete Overflow Flag, delete Timer 1 Compare A
		out TIFR,temp
		IN temp,TIMSK			;Couter 2 Overflow enable
		ORI temp,0b01000000
		OUT TIMSK,temp
		pop temp
		out SREG,temp
		pop temp
		ret		


;***************************************************************************
;*
;* Timer 2 Overflow Interrupt to stop Fashpulse
;*
;***************************************************************************
stopflash:
		push temp				;save Registers
		in temp,SREG
		push temp
		SBI portd,3				;Stop Flash Pulse
		IN temp,TIMSK			;Disable timer2 Overflow Interrupt
		ANDI temp,0b10111111
		OUT TIMSK,temp
		pop temp
		out SREG,temp
		pop temp
		reti

;***************************************************************************
;*
;* compare match A timer 1 interrupt
;*
;***************************************************************************


compare:
		push temp
		IN temp,SREG
		push temp
; Timer set routine
		ldi ZH,high(timetable*2)		;set Z-pointer to Ttimetable adress
		ldi	ZL,low(timetable*2)			;
		add	ZL,shdmxByte		;Set offset in Timetable
		adc	ZH,R1			;
		add ZL,shdmxByte
		adc	ZH,R1	
		LPM R0,Z+			;Readout compare Match Values
		MOV timer_matchH,R0			;
		LPM R0,Z
		MOV timer_matchL,R0
		OUT OCR1AH,timer_matchH		;Set compare Match A
		OUT OCR1AL,timer_matchL
; Timer set routine end
		rcall flash
		pop temp
		OUT SREG,temp
		pop temp
		reti

;***************************************************************************
;*
;* get dmx-byte from uart-data-register
;*
;***************************************************************************

get_byte:
		push temp
		in temp,SREG
		push temp
		push tempL
		push tempH
		in shUCSRA,UCSRA		;UCSRA is cleared when reading UDR !
		in	dmx_Byte,UDR
		sbrc	shUCSRA,3		;check for overrun -> reset
		rjmp	overrun
 		sbrc	shUCSRA,4		;check for receive error -> reset
		rjmp	frame_error

		cpi 	dmx_status,0x01		;wait for reset?
		brne	get_bytea	
		rjmp 	ret1			;return

get_bytea:
		CLC
		cp 	dmx_countL,R1		;startbyte?
		cpc 	dmx_countH,R1		;
		breq	startbyte
		CLC
		cp 	dmx_countL,dmx_adrL	;compare adress and bytenumber	low-byte
		cpc 	dmx_countH,dmx_adrH	;				high-byte
		brlo	return
		breq	first

next_t:	cpi	dmx_count_in,channels_all;if maximal channel reached
		brsh	return

startbyte:
		cp	dmx_Byte,R1		;startbyte=0 
		breq	firstl
		rjmp	overrun			;wait for next reset-cycle
firstl:
		rjmp	return

first:	
		inc	dmx_count_in
		ldi temp,minvalue
		MOV shdmxbyte,dmx_Byte	;Mov Actual DMX Value into Shadow Register
		cp dmx_Byte,temp		;DMX Wert unter minimalwert Timer 1 aus
		brcc first1
		in temp,TIMSK
		ANDI temp,0b11101111	;Clear Compare Match A Mask
		out TIMSK,temp
		CBR status,0b00000001	;Clear single flash sign if set
		rjmp return
first1:
		sbic pinb,5				;Switch single Flash/ continious Flash at Higher Values
		rjmp first2
		ldi temp,maxvalue		;Input > maxvalue -> single Flash is generated
		cp dmx_Byte,temp
		brcs first2
		in temp,TIMSK
		ANDI temp,0b11101111
		out TIMSK,temp			;Stop Timer 2 Compare A
		sbrs status,0
		rcall flash
		sbr status,0b00000001
		rjmp return
first2:
		IN temp,TIMSK
		ORI temp,0b01010000			;Timer 1 Compare Interrupt einschalten
		OUT TIMSK,temp
		CBR status,0b00000001		;Clear Single Flash sign if set

return:	inc 	dmx_countL		;set adress to next channel
		brne	ret1
		inc 	dmx_countH
ret1:	
		pop tempH
		pop tempL
		pop temp
		out SREG,temp
		pop temp
		reti


frame_error:
		ldi temp,0x10				;For flashing LED on received Frame
		inc led_count
		cp led_count,temp
		brcs ledoff
		cbi portd,2
		ldi temp,0x20
		cp led_count,temp
		brcs ledon
		clr led_count
ledoff: sbi portd,2
ledon:
		ldi	dmx_countL,0x00		;reset counter
		ldi	dmx_countH,0x00
		ldi 	dmx_count_in,0x00

	 	ldi 	dmx_status,0x00		;set status byte to 'ok'
 		cbi	UCSRA,FE		;clear frame-error flag

		rcall	start_adress		;get adress

		pop tempH
		pop tempL
		pop temp
		out SREG,temp
		pop temp
		reti

overrun:
	 	ldi	dmx_status,0x01		;set status byte to 'wait for reset'

		pop tempH
		pop tempL
		pop temp
		out SREG,temp
		pop temp
		reti				;return



;***************************************************************************
;*
;* ADC new Value
;*
;***************************************************************************

adcready:
		PUSH tempL
		IN tempL,SREG
		PUSH tempL		
		in shadc,ADCH
		POP tempL
		OUT SREG,tempL
		POP tempL
		reti
	


;***************************************************************************
;*
;* get start adress
;*
;***************************************************************************


start_adress:

		in		tempL,pinb			;get 5 LOW DMX Adress bits
		andi	tempL,0b00011111	;Filter low byte
		in		temp,pind			;get 4 HIGH DMX Adress bits
		andi	temp,0b11110000		;Filter high byte
		ldi		tempH,0xFF			;prepare tempH for High Adress 
		clc							;Carry Flag löschen
		rol		temp				;Shift MSB into carry
		rol		tempH				;Shift Carry into tempH
		or		tempL,temp			;combine to compete Low DMX Adress
		com		tempL				;Invert adress bits
		com		tempH
		mov 	dmx_adrL,tempL		;Transfer to DMX adress registers
		mov 	dmx_adrH,tempH		;

		ret




.cseg
timetable:
	.dw 0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0x20F4,0xA7DD,0xEDCA,0x15BB,0x80AD,0xBBA1,0x6F97
	.dw 0x588E,0x4486,0x0A7F,0x8978,0xA672,0x4D6D,0x6A68,0xF063,0xD15F,0x045C,0x7E58,0x3955,0x2E52,0x574F,0xAE4C,0x304A
	.dw 0xD947,0xA545,0x9243,0x9B41,0xC03F,0xFE3D,0x533C,0xBE3A,0x3C39,0xCC37,0x6E36,0x1F35,0xE033,0xAE32,0x8A31,0x7130
	.dw 0x642F,0x622E,0x6A2D,0x7B2C,0x952B,0xB82A,0xE329,0x1629,0x5028,0x9027,0xD726,0x2526,0x7825,0xD024,0x2E24,0x9123
	.dw 0xF922,0x6622,0xD721,0x4C21,0xC520,0x4220,0xC31F,0x471F,0xCE1E,0x591E,0xE71D,0x781D,0x0C1D,0xA31C,0x3C1C,0xD81B
	.dw 0x761B,0x171B,0xBA1A,0x5F1A,0x071A,0xB019,0x5C19,0x0919,0xB818,0x6918,0x1C18,0xD017,0x8617,0x3E17,0xF716,0xB216
	.dw 0x6E16,0x2B16,0xEA15,0xAA15,0x6B15,0x2E15,0xF214,0xB714,0x7D14,0x4414,0x0C14,0xD513,0xA013,0x6B13,0x3713,0x0413
	.dw 0xD212,0xA112,0x7112,0x4112,0x1312,0xE511,0xB811,0x8B11,0x6011,0x3511,0x0B11,0xE110,0xB810,0x9010,0x6910,0x4210
	.dw 0x1C10,0xF60F,0xD10F,0xAC0F,0x880F,0x640F,0x420F,0x1F0F,0xFD0E,0xDC0E,0xBB0E,0x9A0E,0x7A0E,0x5A0E,0x3B0E,0x1D0E
	.dw 0xFE0D,0xE00D,0xC30D,0xA60D,0x890D,0x6D0D,0x510D,0x350D,0x1A0D,0xFF0C,0xE50C,0xCB0C,0xB10C,0x970C,0x7B0C,0x650C
	.dw 0x4D0C,0x340C,0x1C0C,0x050C,0xED0B,0xD60B,0xBF0B,0xA90B,0x930B,0x7C0B,0x670B,0x510B,0x3C0B,0x270B,0x120B,0xFE0A
	.dw 0xE90A,0xD50A,0xC10A,0xAE0A,0x9A0A,0x870A,0x740A,0x610A,0x4F0A,0x3C0A,0x2A0A,0x180A,0x060A,0xF509,0xE309,0xD209
	.dw 0xC109,0xB009,0x9F09,0x8F09,0x7E09,0x6E09,0x5E09,0x4E09,0x3E09,0x2F09,0x1F09,0x1009,0x0109,0xF208,0xE308,0xD408
	.dw 0xC608,0xB808,0xA908,0x9B08,0x8D08,0x7F08,0x7108,0x6408,0x5608,0x4908,0x3C08,0x2F08,0x2208,0x1508,0x0808,0xFB07
	.dw 0xEF07,0xE207,0xD607,0xCA07,0xBD07,0xB107,0xA607,0x9A07,0x8E07,0x8207,0x7707,0x2107,0x1507,0x0A07,0xFF06,0xA906
	.dw 0x9E06,0x9306,0x8806,0x3306,0x2806,0x1E06,0x1306,0xBE05,0xB405,0xA905,0x9F05,0x4A05,0x4005,0x3605,0x2C05,0x2005
Äh ein Hardwarefehler, wie eine vertauschte + / - Leitung auf der RS485 Schnittstelle kann es nicht sein ?