- 3D-Druck Einstieg und Tipps         
Ergebnis 1 bis 8 von 8

Thema: DMX 512 Empfänger -->> läuft

  1. #1
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    12.06.2006
    Beiträge
    478

    DMX 512 Empfänger -->> läuft

    Anzeige

    LiFePo4 Akku selber bauen - Video
    Hallo zusammen,

    ich habe hier das MINI-USB-DMX-Interface von DMX4ALL, benutzte die DMXControl Software, einen ATmega8 mit 16MHz Quarz und einen MAX485. Der 120 Ohm Abschluss Widerstand ist auch drin.

    Versuche jetzt einen Empfänger zu bauen. Ich habe darauf geachtet, das in DMXControl, im C Quelltext und im Gerätemanager die selben Baudraten und Anzahlen an Stopbits stehen.


    In der ISR des UART, wenn ein Frame ansteht, wird auf Fehlererkennung getestet und wenn kein Fehler anliegt, UDR ausgelesen und auf PORT D gegeben, wo LED´s angeschlossen sind.

    Dies ist mein Code, für den ich mich an anderen orientiert habe, die ich gefunden habe:
    Code:
    #include <avr/io.h>
    #include <avr/interrupt.h>
    
    #define FOSC 16000000// Clock Speed
    #define BAUD 38400
    #define MYUBRR FOSC/16/BAUD-1
    
    volatile unsigned int byte_counter = 0;
    volatile unsigned char befehl [4] = {0};
    volatile unsigned int time;
    volatile unsigned char tmp;
    volatile unsigned int tmp2;
    
    void USART_Init( unsigned int ubrr)
    {
    /* Set baud rate */
    UBRRH = (unsigned char)(ubrr>>8);
    UBRRL = (unsigned char)ubrr;
    /* Enable receiver and transmitter */
    UCSRB = (1<<RXCIE)|(1<<RXEN);//|(1<<TXEN)
    /* Set frame format: 8data, 1stop bit */
    UCSRC = (1<<URSEL)|(3<<UCSZ0);//(1<<USBS)|
    }
    
    
    
    SIGNAL (SIG_UART_RECV)//Frame Recieve Interrupt
    {
    	unsigned char dummy;
    	byte_counter++;
    	if((UCSRA & 0b00010000)== 16)//Frame Error?
    	{//JA/////////////
    		byte_counter = 0;
    		dummy = UDR;
    	}
    	else
    	{ //NEIN/////////////
    		tmp = UDR;
    		if (byte_counter == 3) PORTD = tmp;//Kanal 3 auslesen	
    	}
    	
    
    }
    
    int main (void)
    {
    
    
    USART_Init(MYUBRR);
    DDRD = 0b11111110;
    sei();
    main2:
    
    goto main2;
    return 0;
    }
    Eingestellt ist Kanal drei. Allersings reagiert der Empfänger auch auf andere Kanäle weshalb ich vermute, dass die Starterkennung über den Framefehler nicht funktioniert. Außerdem wird auch nicht der Wert angezeigt, den ich am PC für den Kanal einstelle.

    Erkennt hier jemand einen Fehler?

    mfg,
    The Man
    Chuck Norris kann Windows Vista auf einem Atmel in Assembler implementieren!
    Chuck Norris coded mit 3 Tasten:"1","0" und "compile"

  2. #2
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    12.06.2006
    Beiträge
    478
    Ich habe inzwischen einen Bautratenquarz mit 9.216Mhz eingelötet. Das Problem ist nur, wenn ich im AVR Studio im Programm Tool über "advanced" die externe Taktrate auf Medium stellen will, hat das zur Folge, das mir das Studio bei erneutem öffnen dieser Option anzeigt, ich hätte die Flash Fuses aktiviert und dem entsprechend kann ich den Chip auch nicht mehr flashen. Allerdings zeigt meine Kontrolll LED an, dass das Programm auch bei der Einstellung "High Frequncy" läuft. Weiß jemand denn, ob es stabil laufen kann?
    Denn bei mir schlägt nach wie vor die Error Erkennung an. natürlich habe ich die geänderte Taktrate im Programmkopf angegeben...

    mfg,
    The Man

  3. #3
    Erfahrener Benutzer Robotik Einstein Avatar von wkrug
    Registriert seit
    17.08.2006
    Ort
    Dietfurt
    Beiträge
    2.234
    Läuft DMX nicht mit 250kBit/s ??? Die 38,4 kBit werden doch nur für die Komunikation zwischen dem PC und dem DMX Interface verwendet.

    Auf der DMX Seite läuft das Interface mit den normierten DMX Einstellungen.

    Soweit ich weiß 250kBit, 1 Startbit, 2 Stoppbits, keine Parität, Frame Error als Sync Signal ( Mal so aus dem Kopf heraus, bitte nicht hauen wenns nicht stimmt).

    Ich hab zwar deine Register Einstellungen nicht überprüft, aber eine falsche Baudrate könnte den von Dir geschilderten Effekt haben.

  4. #4
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    12.06.2006
    Beiträge
    478
    Ich habe jetzt diverse Baudraten und Bitraten ausprobiert. Und diese auch in einander umgerechnet. Ist ja nicht das selbe. Jedenfalls komme ich nicht weiter.

    Hat schon mal jemand mit einem AVR DMX empfangen? Welche Baudrate muss ich da einstellen? Habe jetzt auf microcontroler.net ein Programm mit 9600 Baut gefunden.

    mfg,
    The Man

  5. #5
    Erfahrener Benutzer Robotik Einstein Avatar von wkrug
    Registriert seit
    17.08.2006
    Ort
    Dietfurt
    Beiträge
    2.234
    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 ?

  6. #6
    Erfahrener Benutzer Robotik Einstein Avatar von Vitis
    Registriert seit
    06.01.2005
    Ort
    Südpfalz
    Alter
    51
    Beiträge
    2.253
    DMX läuft mit

    250000 8n2 ... die 2 Stopbit sind wichtig.
    Vom Quarz her hab ich dann 16MHz genommen, 8 gehn aber auch
    Bei der Baudrate sind die "runden" Taktraten besser, da weniger
    Fehler.
    Als zusätzlichen Indikator kann man auch den ersten Frame
    noch dazunehmen, der 0 sein sollte.
    also Frame Error und nächstes byte ist null, dann Anfang

    ist zwar bascom, aber mit dem code hab ich gearbeitet mit dmx
    für nen Dimmer:

    Code:
    ' #######################################
    ' DAS IST DER CODE !!!!!!
    
    $regfile = "m8def.dat"
    $crystal = 16000000
    $baud = 250000
    Config Com1 = Dummy , Synchrone = 0 , Parity = None , Stopbits = 2 , Databits = 8
    
    
    Dim Timeout_counter As Byte , X As Byte , Y As Byte , Z As Byte , Fe_error As Byte
    Dim Adresse As Byte , Adresse2 As Byte , Pointer As Byte At &H82
    Dim Timercounter As Byte , Flag As Byte , Summe_pwm As Word
    Dim Pwm_werte(5) As Byte
    Dim Rotation_byte As Byte , Rotation_zaehler As Byte
    
    On Urxc Zeichenempfang
    Enable Urxc
    
    Const Pwm_teiler = 255 / 46
    
    Config Int0 = Falling
    On Int0 Nulldurchgang
    Enable Int0
    
    Config Timer0 = Timer , Prescale = 64
    On Timer0 Timer_irq
    Const Timervorgabe = 220
    Enable Timer0
    
    Enable Interrupts
    Config Portd.2 = Input
    Config Portb = Output
    Config Portc = Input
    ' interne Pullups an
    Portc = &HFF
    
    485_rw Alias Portc.6
    Config 485_rw = Output
    485_rw = 0
    
    Led Alias Portb.0
    
    Adresse = 24
    'Adresse = Pinc
    'Adresse = Not Adresse
    'Adresse = Adresse And &B00111111
    'Adresse = Pinc
    Adresse2 = Adresse
    
    Shift Adresse , Left , 2
    
    For Z = 1 To 4
       Pwm_werte(z) = 2
    Next
    
    Rotation_byte = &B10001000
    
    Do
       If Flag = 1 Then
          Flag = 0
          Y = Pointer
          Shift Y , Right , 2
          If Y = Adresse2 Then
             Y = Pointer
             Y = Y And &B00000011
             Incr Y
             Summe_pwm = Summe_pwm + X
             Pwm_werte(y) = X / Pwm_teiler
             Pwm_werte(y) = 49 - Pwm_werte(y)
          End If
       End If
    
       If Summe_pwm = 1020 Then
          If Rotation_zaehler > 30 Then
             Rotation_zaehler = 0
             Rotate Rotation_byte , Right , 1
          End If
    
          For Y = 1 To 4
              If Rotation_byte.y = 0 Then
                 Pwm_werte(y) = 60
              End If
          Next
       End If
    
        If Timercounter < 48 Then
           If Pwm_werte(1) <= Timercounter Then
             Set Portb.1
           Else
             Reset Portb.1
           End If
           If Pwm_werte(2) <= Timercounter Then
              Set Portb.2
           Else
              Reset Portb.2
           End If
           If Pwm_werte(3) <= Timercounter Then
              Set Portb.3
           Else
              Reset Portb.3
           End If
           If Pwm_werte(4) <= Timercounter Then
             Set Portb.4
           Else
             Reset Portb.4
           End If
        End If
        Waitus 10
        Portb = 0
    
       If Timeout_counter > 150 Then
         For Z = 1 To 4
             Pwm_werte(z) = 100
         Next
         Summe_pwm = 0
       End If
    Loop
    End
    
    Zeichenempfang:
       X = Udr
       If Fe_error = 1 And X = 0 Then
            Fe_error = 0
            Pointer = 0
            Summe_pwm = 0
       End If
       If Ucsra.fe = 1 Then
            Fe_error = 1
            Ucsra.fe = 0
       End If
       Incr Pointer
       Flag = 1
       'Toggle Led
       Timeout_counter = 0
    Return
    End
    
    Nulldurchgang:
       Timercounter = 0
       Incr Timeout_counter
       Incr Rotation_zaehler
    Return
    End
    
    Timer_irq:
      Timer0 = Timervorgabe
      Incr Timercounter
    Return
    End
    Vor den Erfolg haben die Götter den Schweiß gesetzt

  7. #7
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    12.06.2006
    Beiträge
    478
    THX @ all,

    also ich weiß inzwischen nicht mehr, wo hier das Problem war. Hab´s irgendwann geschafft, die Mühle zum mahlen zu bringen.
    Ich stell meinen Code auch noch rein, dann haben wir eine schöne Sammlung an ASM, C und Basic.

    Code:
    #include <avr/io.h>
    #include <avr/interrupt.h>
    
    #define FOSC 16000000// Clock Speed
    #define BAUD 250000
    #define MYUBRR FOSC/16/BAUD-1
    #define ziel_adr 1 // hier die Adresse des Gerätes angeben
    #define real_adr ziel_adr+1//trägt dem führenden Nullbyte rechnung
    
    volatile unsigned int byte_counter = 0;
    volatile unsigned char befehl [4] = {0};
    volatile unsigned int time;
    volatile unsigned char tmp;
    volatile unsigned int tmp2;
    
    void USART_Init( unsigned int ubrr)
    {
    /* Set baud rate */
    UBRRH = (unsigned char)(ubrr>>8);
    UBRRL = (unsigned char)ubrr;
    /* Enable receiver and Interrupt*/
    UCSRB = (1<<RXCIE)|(1<<RXEN);//|(1<<TXEN)
    /* Set frame format: 8data, 2stop bit */
    UCSRC = (1<<URSEL)|(1<<USBS)|(3<<UCSZ0);//
    }
    
    
    
    SIGNAL (SIG_UART_RECV)//Frame Recieve Interrupt
    {
    	unsigned char dummy;
    
    	
    	//PORTD =byte_counter;
    	if((UCSRA & 0b00010000)== 16)//Frame Error?
    	{//JA/////////////
    		byte_counter = 0;
    		dummy = UDR;
    		UCSRA &= 0b11101111;
    	}
    	else
    	{ //NEIN/////////////
    		tmp = UDR;
    		if (byte_counter == real_adr) PORTD = tmp;	
    	}
    	byte_counter++;
    
    }
    
    int main (void)
    {
    
    
    USART_Init(MYUBRR);
    DDRD = 0b11111110;
    sei();
    main2:
    
    goto main2;
    return 0;
    }
    Chuck Norris kann Windows Vista auf einem Atmel in Assembler implementieren!
    Chuck Norris coded mit 3 Tasten:"1","0" und "compile"

  8. #8
    Hey könnte es sein dass, das auslessen mit 8Mhz nicht funktionier?

    Mein code funktioniert nicht und der C code von hier funktioniert auch nicht... Warum denn das!!!?


    Code:
    #include <avr/io.h>
    #include <avr/interrupt.h>
    #include <avr/iom48.h>
    
    #define FOSC 6000000// Clock Speed
    #define BAUD 250000
    #define MYUBRR FOSC/16/BAUD-1
    #define ziel_adr 1 // hier die Adresse des Gerätes angeben
    #define real_adr ziel_adr+1//trägt dem führenden Nullbyte rechnung
    
    volatile unsigned int byte_counter = 0;
    volatile unsigned char befehl [4] = {0};
    volatile unsigned int time;
    volatile unsigned char tmp;
    volatile unsigned int tmp2;
    
    void USART_Init( unsigned int ubrr)
    {
    /* Set baud rate */
    UBRR0H = (unsigned char)(ubrr>>8);
    UBRR0L = (unsigned char)ubrr;
    /* Enable receiver and Interrupt*/
    UCSR0B = (1<<RXCIE0)|(1<<RXEN0);//|(1<<TXEN)
    /* Set frame format: 8data, 2stop bit */
    UCSR0C = (1<<USBS0)|(3<<UCSZ00);//|(1<<URSEL0);//
    }
    
    
    
    SIGNAL (SIG_UART_RECV)//Frame Recieve Interrupt
    {
       unsigned char dummy;
    
       
       //PORTD =byte_counter;
       if((UCSR0A & 0b00010000)== 16)//Frame Error?
       {//JA/////////////
          byte_counter = 0;
          dummy = UDR0;
          UCSR0A &= 0b11101111;
       }
       else
       { //NEIN/////////////
          tmp = UDR0;
          if (byte_counter == real_adr) PORTB = tmp;   
       }
       byte_counter++;
    
    }
    
    int main (void)
    {
    
    
    USART_Init(MYUBRR);
    DDRB = 0b11111110;
    sei();
    main2:
    
    goto main2;
    return 0;
    }

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

fchao-Sinus-Wechselrichter AliExpress