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,
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.