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.