Da es nun doch schon über nen Monat her is mach ich dazu mal nen neuen
Thread auf...
Dann frisch ans Werk
Ich will die Schaltung im Anhang als Weichen/Signaldekoder verwenden
(Eigentlich benutze ich einen AtTiny45 aber den gabs in Eagle nicht)
Dabei ist PB2 ein Eingang mit eingeschaltetem Pull-Up Widerstand, wobei
der Externe Interrupt bei fallenden Flanken triggert.
Momentan soll der Dekoder bei Empfang eines vollständigen DCC-Telegramms
(Präambel, LowAdresse, HighAdresse, Checksum) die LED an PORTB3
einschalten.
Das ganze, falls ich es ans Gleis anschließes funktioniert auch
grundsätzlich, allerdings muss ich in meiner CS2 bisweilen eine
DCC-Weiche 8 mal umschalten bis der Dekoder ein vollständiges Telegramm
erhält und die LED einschaltet.
Nun meine Frage an alle die sich auf dem Gebiet auskennen.
Könnt ihr mir irgendwelche Verbesserungen vorschlagen (Sowohl in
Elektronik als auch Programm), damit der Dekoder bestenfalls besser
läuft?
Zum auswerten benutze ich folgenden Code
(Ich hoffe ihr nehmt mir die fehlende Kommentierung nicht all zu übel,
für den der sich in DCC auskennt sollten die jump-ziele eigentlich
Kommentierung genug sein)
1
; Mikrocontroller: ATtiny45
2
; -------------
3
;(RESET)PB5 =| |= VCC
4
; | |
5
; (O)PB3 =| |= PB2(INT0)
6
; | |
7
; PB4 =| |= PB1
8
; | |
9
; GND =| |= PB0
10
; -------------
11
;
12
; Taktgeber: Interner Oszillator
13
; Taktfrequenz: 8 MHz
14
; Zykluszeit: 125ns
15
;
16
; Brown-out Detection: 2,7V
17
18
.set PR = 7 ; präambel-Flag
19
.set AL = 6 ; adresseLow-Flag
20
.set AH = 5 ; adresseHigh-Flag
21
.set CS = 4 ; checksum-Flag
22
23
.def adresseLow = r0
24
.def adresseHigh = r1
25
.def checksum = r2
26
.def bitCounter = r19
27
.def DCCREG = r20
28
29
.include "tn45def.inc" ; Definitionsdatei für den AtTiny45 einbinden
Michael E. schrieb:> praeambel1:> inc bitCounter>> cpi bitCounter, 15> brcc dccreset> reti
Wie kommst du auf die 15?
Minimum für Sync sind 10 Bits, Norm für Zentralen sind >=16 Bits.
<10 Bits darf er nicht, >=12 muß der Dekoder erkennen. Aber 15?
Michael E. schrieb:> ldi r16, 87> out OCR0A, r16
88µs könnten zu lang sein. Wenn nämlich die Timer-ISR noch läuft und die
Flanke vom nächsten Bit schon ansteht, kommt die INT0-ISR entsprechend
später. Und mit jedem weiteren 1-Bit wird es noch knapper. Die Toleranz
des RC-Oszillators tut evtl. noch ihr Übriges dazu.
Puh dachte schon es meldet sich gar niemand mehr :D
Hab auf einer Seite gelesen dass es maximal 14 1en in der Präambel sein
dürfen
und da es dementsprechend 14 sein dürfen wird die carry-flag, die ich
danach ja abfrage, erst gecleart wenn es 15 werden.
Dann war wohl die Telegramm beschreibung der Seite falsch.
Zum zweiten
Da hatte ich auch schon drüber nachgedacht. Was denkst du welchen Wert
ich benutzen sollte?
Michael
Michael E. schrieb:> Hab auf einer Seite gelesen dass es maximal 14 1en in der Präambel sein> dürfen
Ja, das steht auf Wikipedia. Das war wohl auch mal Usus. Aber die Norm
sagt 16. Da er 10 Syncs als richtige Präambel erkennen soll, solltest du
auf >=10 nach dem Empfang einer 0 testen. Wenn du während des Empfangs
immer die 1-Bits mitzählst und bei einem 0-Bit den Zähler testest, hast
du immer ein Sync empfangen wenn der Zähler >=10 ist. Natürlich muß der
Zähler nach dem Empfang einer 0 immer gelöscht werden.
Michael E. schrieb:> Was denkst du welchen Wert> ich benutzen sollte?
Ich frage nach 75µs ab.
Hab es zwar nicht auf Wikipedia gelesen aber ist gut zu wissen
Bin auf 75 µs runter und die Abfrage bei 0 hatte ich ja im Code oben
sowieso schon drin.
Werde da jetzt mal weiter probieren. Danke
Michael
Hallo Michael,
warum das Rad immer wieder neu erfinden. Nehme den Decoder von Toralf
wilhelm und gut ist. Da kannst Du im Sourcecode einiges lernen. Außerdem
gibt es fertige Platinen.
Gruß
Roman