Hallo Alle Ich möchte das erste Byte (Kanal) vom DMX512 auf ein LCD anzeigen lassen. Die anderen Kanäle sind später mal dran. Dazu habe ich einen 8515 mit 8MHz auf dem STK500. Im Simulator läuft alles korrekt. Nur macht der Controller nicht so mit, wie er es soll. Quarz, 75176 und Controller sind schon getauscht, daran liegt es nicht. Die Bit’s 0,1 und 2 haben immer 010 als Ergebnis. Also ist das Resultat ja keineswegs der wirkliche Wert. Ist da irgendwo einen Fehler drin und ich sehe den nicht? Es währe nett wenn da mal einer darüber sehen könnte. ; 8515 mit 8MHz .include "8515def.inc" .EQU BlinkOff = 0b00001100 ;LCD An und Blinken aus .EQU LCD_Aus = 0b00001000 ;LCD Ausschalten .EQU LCD_Pos1 = 0b10000000 ;1. Zeile 1pos .EQU LCD_Pos2 = 0b11000000 ;2. Zeile 1pos .EQU RxD =0 ;Receive pin ist PD0 .def temp = r16 .def temp1 = r17 .def temp2 = r18 .def temp3 = r19 .def bitcnt =R20 .def RXbyte =R21 .def adressL =R22 .def bytecntL=R23 .def TempL =R24 .def Timer =R25 .org $000 rjmp INIT ;Program/Reset Handler .org INT0addr reti ;External Interrupt0 Vector Address .org INT1addr reti ;External Interrupt1 Vector Address .org ICP1addr reti ;Input Capture1 Interrupt Vector Address .org OC1Aaddr reti ;Output Compare1A Interrupt Vector Address .org OC1Baddr reti ;Output Compare1B Interrupt Vector Address .org OVF1addr reti ;Overflow1 Interrupt Vector Address .org OVF0addr reti ;Overflow0 Interrupt Vector Address .org SPIaddr reti ;SPI Interrupt Vector Address .org URXCaddr reti ;UART Receive Complete Interrupt Vector Address .org UDREaddr reti ;UART Data Register Empty Interrupt Vector Address .org UTXCaddr reti ;UART Transmit Complete Interrupt Vector Address .org ACIaddr reti ;Analog Comparator Interrupt Vector Address .org 0x010 init: ldi temp1,High(RamEnd) out sph,temp1 ldi temp1,Low(RamEnd) out spl,temp1 ldi temp1, 0x00 out DDRA, temp1 ;Port A = Eingang out DDRD, temp1 ;Port D = Eingang ldi temp1, 0xFF out DDRB, temp1 ;Port B = Ausgang out DDRC, temp1 ;Port C = Ausgang rcall lcd_init ;Display initialisieren rcall lcd_clear ;Display löschen loop: check_reset: sbis PIND,Rxd ;warte auf high rjmp check_reset check_1: clc ;lösche carry sbic PIND,Rxd ;warte auf low rjmp check_1 ldi TempL,234 ;reset länge 234 @ 8 mhz =88µs check_2: sbic PIND,Rxd ;ist pin high sec ;set carryflag brcs check_1 ;nein, es sind daten dec TempL brne check_2 ;warte bis break vorbei ist ldi bytecntL,0 ;reset bytecounter start: inc bytecntL ;Adresse mitzählen forever: sbis PIND,Rxd ;end reset und end mark rjmp forever getdata: ldi bitcnt,9 ;8 data bit + 1 start bit getdata1: sbic PIND,RxD ;warte auf start bit rjmp getdata1 rcall delay_half ;0.5 bit delay verzögern getdata2: rcall delay ;1 bit delay verzögern clc ;lösche carry sbic PIND,RxD ;ist RX pin high sec ;setze carry dec bitcnt ;bitzähler breq getdata3 ;wenn 8 bit gelesen return ;else ror RXbyte ;schiebe carrybit in Rxbyte rjmp getdata2 ;nächstes bit lesen getdata3: ;sbic PIND,RxD ;ist RX pin high dann ist es stop bit rjmp anzeige ;Wert anzeigen ;neuen kanal testen...... ;rjmp start ;neuen Wert lesen anzeige: out portb, rxbyte mov temp,RXbyte rcall bcd rjmp loop
Mensch, da hast Du Dir aber viel Mühe gemacht. Leider bin ich noch neu im ASM, daher fällt es mir nicht leicht, Deinen Code zu überprüfen. Hatte auch schon mal dran gedacht, DMX-Signale auszuwerten. Hätte es einfach den UART machen lassen. Der macht das ganze Handling. Du mußt dann nur noch den Break auswerten und die Kanäle zählen. In der Zwischenzeit ist der µC frei. Aber nun zu Deinem Problem: Hast Du berücksichtigt, daß das Datenformat Start+8Data+2Stop ist? Du hast, glaube ich, nur eines ausgewertet. Bitte verzeihe, wenn ich Dir damit zu blöd komme und Dir nicht weiterhelfen konnte.
Der interne UART eignet sich recht gut zum Verarbeiten von DMX-Signalen. Die BREAK Erkennung kannst du recht zuverlässig über die Auswertung des FE-Errors machen. Das ganze mittels RXC Interrupt und die bleibt noch jede Menge Zeit die empfangenen Daten auch auszuwerten und anzuzeigen.
Danke für eure Antworten. Wenn das mit der Uart besser gehen soll, habt ihr da ein Beispiel? Damit habe ich mich auch Ergebnislos beschäftigt, oder ich bin an der Stelle zu Dumm :(
Hallo Das ist mein versuch mit der Uart. Geht aber auch nicht. Ist da ein Fehler den ich nicht sehe? Wer hat ein Bespiel das auch funktioniert? Gibt es eine andere Lösung? Ich bin für jeden Hinweis offen. ;8515 mit 8MHz .include "8515def.inc" .EQU BlinkOff = 0b00001100 ;LCD An und Blinken aus .EQU LCD_Aus = 0b00001000 ;LCD Ausschalten .EQU LCD_Pos1 = 0b10000000 ;1. Zeile 1pos .EQU LCD_Pos2 = 0b11000000 ;2. Zeile 1pos .equ STARTBIT =1 ;Start bit flag .equ NEWDATA =2 ;New data flag .equ UPPERDA =3 ;When 1 We are on Current Byte + 256 (IE CB = 10 then .def temp = r16 .def temp1 = r17 .def temp2 = r18 .def temp3 = r19 .def BYTE1 =R20 ;bit counter* .def RXbyte =R21 ;Received data* .def adressL =R22 ;adress registe .def FLAGT =R23 ;byte counter low* .def TempL =R24 ;temporary storage register low* .def CURRENTBYTE =R25 .def Data =R26 .org $000 rjmp INIT ;Program/Reset Handler .org INT0addr reti ;External Interrupt0 Vector Address .org INT1addr reti ;External Interrupt1 Vector Address .org ICP1addr reti ;Input Capture1 Interrupt Vector Address .org OC1Aaddr reti ;Output Compare1A Interrupt Vector Address .org OC1Baddr reti ;Output Compare1B Interrupt Vector Address .org OVF1addr reti ;Overflow1 Interrupt Vector Address .org OVF0addr reti ;Overflow0 Interrupt Vector Address .org SPIaddr reti ;SPI Interrupt Vector Address .org URXCaddr rjmp RX_sub ;UART Receive Complete Interrupt Vector Address .org UDREaddr reti ;UART Data Register Empty Interrupt Vector Address .org UTXCaddr reti ;UART Transmit Complete Interrupt Vector Address .org ACIaddr reti ;Analog Comparator Interrupt Vector Address .org 0x010 ;Code follows from here init: ldi temp1,High(RamEnd) out sph,temp1 ldi temp1,Low(RamEnd) out spl,temp1 ldi temp1, 0x00 out DDRA, temp1 ;Port A = Eingang out DDRD, temp1 ;Port D = Eingang ldi temp1, 0xFF out DDRB, temp1 ;Port B = Ausgang out DDRC, temp1 ;Port C = Ausgang ldi TEMPL,0x01 ;set baudrate to 250K (8Mhz xtal) out UBRR,TEMPL sbi UCR,RXEN ;enable serial recieve interrupts sbi UCR,RXCIE sbi UCR,CHR9 ;enable 9 bit data in adressL,pinA ;Adresse von Port laden sei rcall lcd_init ;Display initialisieren rcall lcd_clear ;Display löschen ldi temp1, 'D' ;Zeichen anzeigen rcall lcd_data ldi temp1, 'a' ;Zeichen anzeigen rcall lcd_data ldi temp1, 't' ;Zeichen anzeigen rcall lcd_data ldi temp1, ':' ;Zeichen anzeigen rcall lcd_data loop: ;cli anzeige: out portb, data mov temp,data rcall bcd in adressL,pinA ;Adresse von Port laden ;mov temp,adressL ;rcall bcd ;sei rjmp loop ;****************************************************** RX_sub: push TEMPL in TEMPL,SREG push TEMPL in DATA,UDR sbis UCR,RXB8 rjmp NODATA ldi TEMPL,0x00 cp TEMPL,CURRENTBYTE brne CURRENTBYTE1 ldi TEMPL,0x00 cp TEMPL,DATA brne NODATA rjmp ENDR CURRENTBYTE1: cp CURRENTBYTE,adressL brne ENDR mov BYTE1,DATA sbrs FLAGT,3 sbr FLAGT,2 ENDR: clc inc CURRENTBYTE brbc 1,ENDR1 sbr FLAGT,3 ENDR1: pop TEMPL out SREG,TEMP pop TEMPL reti NODATA: ldi TEMPL,0x00 mov CURRENTBYTE,TEMPL cbr FLAGT,3 rjmp ENDR1 ;******************************************************
Hallo, wenn ich mich nicht irre, ist das doch der Code von Martin Schneebacher, oder? Kannst du den nicht vollständig übernehmen und auf den Proz laden (vielleicht ein Parr Interruptvektoren ändern), das müsste doch gehen. Und dann eben auf das erste byte beschränken. Viel Erfolg Phil
Das ist der Code von Martin. Nur eben auf einem 1200'er mit 12 MHz, dehalb auch die Spielerei mit den Warteschleifen. Aber wie gesagt, ohne Erfolg. Die Bits 0, 1 und 2 stehen immer auf 010.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.