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.
.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,0 xFFFF,0xFFFF,0x20F4,0xA7DD,0xEDCA,0x15BB,0x80AD,0x BBA1,0x6F97
.dw 0x588E,0x4486,0x0A7F,0x8978,0xA672,0x4D6D,0x6A68,0 xF063,0xD15F,0x045C,0x7E58,0x3955,0x2E52,0x574F,0x AE4C,0x304A
.dw 0xD947,0xA545,0x9243,0x9B41,0xC03F,0xFE3D,0x533C,0 xBE3A,0x3C39,0xCC37,0x6E36,0x1F35,0xE033,0xAE32,0x 8A31,0x7130
.dw 0x642F,0x622E,0x6A2D,0x7B2C,0x952B,0xB82A,0xE329,0 x1629,0x5028,0x9027,0xD726,0x2526,0x7825,0xD024,0x 2E24,0x9123
.dw 0xF922,0x6622,0xD721,0x4C21,0xC520,0x4220,0xC31F,0 x471F,0xCE1E,0x591E,0xE71D,0x781D,0x0C1D,0xA31C,0x 3C1C,0xD81B
.dw 0x761B,0x171B,0xBA1A,0x5F1A,0x071A,0xB019,0x5C19,0 x0919,0xB818,0x6918,0x1C18,0xD017,0x8617,0x3E17,0x F716,0xB216
.dw 0x6E16,0x2B16,0xEA15,0xAA15,0x6B15,0x2E15,0xF214,0 xB714,0x7D14,0x4414,0x0C14,0xD513,0xA013,0x6B13,0x 3713,0x0413
.dw 0xD212,0xA112,0x7112,0x4112,0x1312,0xE511,0xB811,0 x8B11,0x6011,0x3511,0x0B11,0xE110,0xB810,0x9010,0x 6910,0x4210
.dw 0x1C10,0xF60F,0xD10F,0xAC0F,0x880F,0x640F,0x420F,0 x1F0F,0xFD0E,0xDC0E,0xBB0E,0x9A0E,0x7A0E,0x5A0E,0x 3B0E,0x1D0E
.dw 0xFE0D,0xE00D,0xC30D,0xA60D,0x890D,0x6D0D,0x510D,0 x350D,0x1A0D,0xFF0C,0xE50C,0xCB0C,0xB10C,0x970C,0x 7B0C,0x650C
.dw 0x4D0C,0x340C,0x1C0C,0x050C,0xED0B,0xD60B,0xBF0B,0 xA90B,0x930B,0x7C0B,0x670B,0x510B,0x3C0B,0x270B,0x 120B,0xFE0A
.dw 0xE90A,0xD50A,0xC10A,0xAE0A,0x9A0A,0x870A,0x740A,0 x610A,0x4F0A,0x3C0A,0x2A0A,0x180A,0x060A,0xF509,0x E309,0xD209
.dw 0xC109,0xB009,0x9F09,0x8F09,0x7E09,0x6E09,0x5E09,0 x4E09,0x3E09,0x2F09,0x1F09,0x1009,0x0109,0xF208,0x E308,0xD408
.dw 0xC608,0xB808,0xA908,0x9B08,0x8D08,0x7F08,0x7108,0 x6408,0x5608,0x4908,0x3C08,0x2F08,0x2208,0x1508,0x 0808,0xFB07
.dw 0xEF07,0xE207,0xD607,0xCA07,0xBD07,0xB107,0xA607,0 x9A07,0x8E07,0x8207,0x7707,0x2107,0x1507,0x0A07,0x FF06,0xA906
.dw 0x9E06,0x9306,0x8806,0x3306,0x2806,0x1E06,0x1306,0 xBE05,0xB405,0xA905,0x9F05,0x4A05,0x4005,0x3605,0x 2C05,0x2005
Äh ein Hardwarefehler, wie eine vertauschte + / - Leitung auf der RS485 Schnittstelle kann es nicht sein ?
Powered by vBulletin® Version 4.2.5 Copyright ©2024 Adduco Digital e.K. und vBulletin Solutions, Inc. Alle Rechte vorbehalten.