; *************************************************************** ; * Copyright by mad.dax@t-online.de * ; * DCC-Decoder Testversion * ; * 14 / 28 und 126 Fahrstufen ( Fahrstufe 14 = 27 ) * ; * Übergänge Stufenlos * ; * PWM mit 6125 HZ, internes Timing mit CV6 trimmbar * ; | ----------------------------------------------------------- | ; | Änderungen von hannes.lux@gmx.de am 05.12.08: | ; | | ; | PWM-Frequenz durch Konstante "fpwm" im Kopf des Quelltextes | ; | an den Motor anpassbar | ; | Autom. Anpassung der Startwerte für Anfahren und Bremsen | ; | (CV3 und CV4) anhand der PWM-Frequenz | ; | Kalibration des internen RC-Oszillators mittels "calibyte" | ; | im Kopf des Quelltextes | ; | Adresse durch Konstante "adress" im Kopf des Quelltextes | ; | einstellbar | ; | ----------------------------------------------------------- | ; * kurze und lange Adressierung ( 7 und 14 Bit je nach CV ) * ; * F1 / F2 als Ausgänge, F3 als Rangiergang * ; * Programming on the Track mit DDW-Server V 0.7.5 und * ; * Java DCC Railroad Network Client V 4.11 getestet * ; * Bedienung auch mit GPlan V 0.70 getestet * ; * Version: 06.06 in Arbeit * ; *************************************************************** ;Eingefügt von Hannes Lux am 05.12.08: ;Konstanten zur Parametrierung: .equ calibyte=$15 ;individuelles Calibrationsbyte dieses Controllers .equ fpwm=9 ;Timer1-Vorteiler im Fahrmode 5=1,6=2,7=4,8=8,9=16,10=32,11=64 .equ adress=2 ;Adresse für neuen Decoder .equ cv3_4=255>>(fpwm-3) ;Startwerte für CV3 und CV4 (Anfahren/Bremsen) ;Ende Einfügung... ; ; Hardware Anforderungen: ; ; Standard Belegung ; ; Tiny 15 PDIP/SOIC ; ;(RESET/ADC0) PB5 = 1 8 = VCC ;(ADC3) PB4 = 2 7 = PB2 (ADC1/SCK/T0/INT0) ;(ADC2) PB3 = 3 6 = PB1 (AIN1/MISO/OC1A) ; GND = 4 5 = PB0 (AIN0/AREF/MOSI) ; ; DCC Decoder ; ;RESET PB5 = 1 8 = VCC ;Funktion 2 PB4 = 2 7 = PB2 DCC Eingang ;Funktion 1 PB3 = 3 6 = PB1 Ausgang Rückwärts ; GND = 4 5 = PB0 Ausgang Vorwärts ;NB: NMRA-DCC Basisprotokoll (abs. FRU, 7-bit-Adr., 14 FS) ;N1: NMRA-DCC erweitert (abs. FRU, 7-bit-Adr., 5 Funkt., 28 FS) ;N2: NMRA-DCC erweitert (abs. FRU, 7-bit-Adr., 5 Funkt., 128 FS) ;N3: NMRA-DCC erweitert (abs. FRU, 14-bit-Adr., 5 Funkt., 28 FS) ;N4: NMRA-DCC erweitert (abs. FRU, 14-bit-Adr., 5 Funkt., 128 FS) ; ; Software Funktionen: ; .NOLIST .INCLUDE "tn15def.inc" ; ; Konstanten FlagReg ; .equ CONREV=4 ;Consist Reverse Direction bei 1 .equ SERVMODE=3 ;Programmiermodus .equ BitNew=2 ;Flag Neues Bit eingetroffen .equ LoTiF=1 ;Long Time Flag .equ Bit=0 ;Bit Wert ; Konstanten DCCReg ; .equ LongADR=7 ;Lange Adresse bei 1 .equ RevDir=6 ;Fahrtrichtung reversiert bei 1 .equ DIR=5 ;Fahrtrichtung 1=vorwärts, 0=rückwärts .equ FL=4 ;FL .equ F4=3 ;F4 nicht benutzt .equ F3=2 ;F3 Rangiergang bei 1-Signal .equ F2=1 ;F2 .equ F1=0 ;F1 .equ SampleTime = 255 - 105 ;139- ca. 30 Befehlszyklen 75% der High-Signal Periodendauer = 87us ohne Precaler .equ WaitTime = 255 - 200 ;250? maximale Bitlänge = 10000us bei Prescaler 64 .equ EEAdresse = 0 ;Speicherplatz eigene Adresse im EEPROM .equ EEStart = 1 ;Speicherplatz Start-Speed nicht benutzt .equ EEIncrease = 2 ;Speicherplatz Beschleunigungskonstante im EEPROM .equ EEDecrease = 3 ;Speicherplatz Verzögerungskonstante im EEPROM .equ EEMaxSpeed = 4 ;Speicherplatz Höchstgeschwindigkeit im EEPROM .equ EEOSCCAL = 5 ;Speicherplatz OSCCAL im EEPROM .equ EELongADR = 28 ;Speicherplatz Lange Adresse gesetzt im EEPROM .equ EELongADRHI =16 ;Speicherplatz Lange Adresse EEPROM .equ EELongADRLO = 17 ;Speicherplatz Lange Adresse EEPROM .equ EECONAdr = 18 ;Speicherplatz Consist Adresse EEPROM .equ ACKTime = 63 ;5 ms bei Timer 1 = CK/128 .equ RESTime = 250 ;20 ms bei Timer 1 = CK/128 ; ; Benutzte Register ; .def RAM = R0 ;Reserviert für RAM Zugriff .def ISTSpeed = R1 ;berechnete Geschwindigkeit .def SOLLSpeed = R2 ;Soll Geschwindigkeit .def IncCnt = R3 ;Beschleunigungszähler/Bremszähler .def IncVAL = R4 ;Beschleunigungkonstante .def IncCnt1 = R5 ;Beschleunigungszähler/Bremszähler .def DecVAL = R6 ;Bremskonstante .def MaxSpeed = R7 ;Höchstgeschwindigkeit .def ByteA = R8 ;Empfangenes Byte .def ByteB = R9 ;Empfangenes Byte .def ByteC = R10 ;Empfangenes Byte .def ByteD = R11 ;Empfangenes Byte .def ByteE = R12 ;Empfangenes Byte .def ByteF = R13 ;Empfangenes Byte .def HIAdresse = R14;eigene Adresse HI-Byte für lange Adresse .def LoAdresse = R15;eigene Adresse Lo-Byte für lange Adresse .def TEMPS = R16 ;SREG Sicherungsregister .def TEMPI = R17 ;TEMP Register für Initialisierung und Interupt-Schmierregister .def TEMP1 = R18 ;TEMP Register für Hauptprogramm und Initialisierung .def TEMP2 = R19 ;TEMP Register für Hauptprogramm .def TEMP3 = R20 ;TEMP Register für Hauptprogramm .def CONAdr = R21 ;Consist-Adresse ( Mehrfachtraktion ) .def Adresse = R22 ;eigene Adresse .def FlagReg = R23 ;Flag Register .def DCCReg = R24 ;DCC Register für Funktionen und Fahrtrichtung .def ByteCNT = R25 ;Bytezähler für Datenhandling .def BitCNT = R26 ;Bitzähler für Datenhandling .def PRGCHECK = R27 ;Checkbyte für CV Schreiben ;def FREI = R28 ;def FREI = R29 ;def Reserviert = R30 ;def Reserviert = R31 ; ; ; Code beginnt hier ; .CSEG .ORG $0000 ; ; Reset- und Interrupt-Vektoren rjmp RESET ; Reset handler rjmp EXT_INT0 ; IRQ0 handler reti ;rjmp PIN_CHANGE ; Pin change handler reti ;rjmp TIM1_CMP ; Timer1 compare match rjmp TIM1_OVF ;Timer1 overflow handler rjmp TIM0_OVF ;Timer0 overflow handler reti ;rjmp EE_RDY ;EEPROM Ready handler reti ;rjmp ANA_COMP ;Analog Comparator handler reti ;rjmp ADCC ;ADC Conversion Handler ; **************** Ende der Interrupt-Sprungtabelle ********************* ; ; ; 8x8 Bit Unsigned Multiplication von ATMEL ;def TEMP1 =r16 ;multiplicand ;def TEMP2 =r17 ;multiplier ;def TEMP2 =r17 ;result Low byte ;def TEMP3 =r18 ;result High byte MUL8X8: clr TEMP3 ;clear result High byte ldi ByteCNT,8 ;init loop counter lsr TEMP2 ;rotate multiplier MULSTART: brcc MULMORE ;carry set add TEMP3,TEMP1 ;add multiplicand to result High byte MULMORE: ror TEMP3 ;rotate right result High byte ror TEMP2 ;rotate right result L byte and multiplier dec ByteCNT ;decrement loop counter brne MULSTART ;if not done, loop more ret writeEEPROM: sbic EECR,EEWE ;wird momentan noch geschrieben ? rjmp PC-1 ;Schleife out EEAR,TEMP1 ;Erfasse EEProm Schreibadresse out EEDR,TEMP2 ;Erfasse EEProm Schreibdaten cli ;alle Interrupts ausschalten sbi EECR,EEMWE ;Setze EEProm Master-Schreibbit sbi EECR,EEWE ;Setze EEProm Schreib-Befehl sbic EECR,EEWE ;wird momentan noch geschrieben ? rjmp PC-1 ;Schleife sei ;alle Interrupts wieder einschalten ret ;Rücksprung readEEPROM: sbic EECR, EEWE ;wird noch geschrieben ? rjmp PC-1 ;Schleife out EEAR, TEMP1 ;Erfasse EEProm-Leseadresse sbi EECR, EERE ;Setze EEProm-Lesebefehl in TEMP2, EEDR ;Lese EEprom-Daten ret ;Rücksprung EXT_INT0: ;Pegelwechsel von Low auf High in TEMPS,SREG ;SREG sichern clr TEMPI ;Timer anhalten out TCCR0,TEMPI ;Prescaler steht auf STOP-Counter mit 000 in TEMPI,TIFR ;lösche Timer 0 Interrupt Flag andi TEMPI,0b00000010 ;das eventuell während dieses Interuptaufrufes out TIFR,TEMPI ;gesetzt worden ist cbr FlagReg,(1< SOLL breq Gleich ;wenn Wert nicht gleich brsh DECSpeed ;wenn Wert größer gleich brlo INCSpeed ;wenn Wert kleiner Gleich: clr IncCNT ;lösche Beschleunigungszähler clr IncCNT1 ;lösche Beschleunigungszähler out SREG,TEMPS ;SREG rücksichern reti ;Rücksprung und Interupts wieder einschalten INCSpeed: cp IncCNT,IncVAL ;vergleiche Beschleunigungszähler brne OVF1 ;Springe wenn kleiner clr IncCNT ;lösche Beschleunigungszähler clr IncCNT1 ;lösche Beschleunigungszähler inc ISTSpeed ;erhöhe Speed rjmp PWMOut ;weiter DECSpeed: cp IncCNT,DECVAL ;vergleiche Beschleunigungszähler brne OVF1 ;Springe wenn kleiner clr IncCNT ;lösche Beschleunigungszähler clr IncCNT1 ;lösche Beschleunigungszähler dec ISTSpeed ;verringere Speed PWMOut: tst ISTSpeed ;ist Speed 0 brne OUTZ ;dann 0 ansonsten Out ldi TEMPI,0b01000101 ;Timer/Counter1 PWM vom out TCCR1,TEMPI ;Ausgang trennen cbi PortB, PB0 ;alles auf Null out SREG,TEMPS ;SREG rücksichern reti ;Rücksprung und Interupts wieder einschalten OUTZ: sbrs DCCReg,DIR ;wenn Fahrtrichtung vorwärts rjmp REV ;überspringe setzen Ausgang rückwärts cbi PORTB,PB0 ;setze Ausgang für vorwärts out OCR1A,ISTSpeed ;Wert für Speed nach Timer 1 Compare ;geändert von Hannes Lux am 05.12.08: ;deaktiviert: ; ldi TEMPI,0b01101011 ;Timer/Counter1 PWM ;hinzugefügt: ldi TEMPI,$60+fpwm ;Timer1 im PWM-Mode vorwärts mit Fahr-Vorteiler ;Sinn: ;Möglichkeit der Anpassung der PWM-Frequenz an die Eigenschaften des Motors ;Ende... out TCCR1,TEMPI ;Ausgang direkt out SREG,TEMPS ;SREG rücksichern reti ;Rücksprung und Interupts wieder einschalten REV: sbi PORTB,PB0 ;setze Ausgang für rückwärts out OCR1A,ISTSpeed ;Wert für Speed nach Timer 1 Compare ;geändert von Hannes Lux am 05.12.08: ;deaktiviert: ; ldi TEMPI,0b01111011 ;Timer/Counter1 PWM ;hinzugefügt: ldi TEMPI,$70+fpwm ;Timer1 im PWM-Mode rückwärts mit Fahr-Vorteiler ;Sinn: ;Möglichkeit der Anpassung der PWM-Frequenz an die Eigenschaften des Motors ;Ende... out TCCR1,TEMPI ;Ausgang indirekt OVF1: out SREG,TEMPS ;SREG rücksichern reti ;Rücksprung und Interupts wieder einschalten TIM0_OVF: in TEMPS,SREG ;SREG sichern clr TEMPI ;Timer anhalten out TCCR0,TEMPI ;Prescaler steht auf STOP-Counter mit 000 sbrs FlagReg,LoTiF ;ist der Interrupt wegen der Sample-Zeit ausgeloest worden rjmp SAMPLE ;ja, dann sample das Bit clr BitCnt ;nein, dann loesche den BitCounter wieder clr ByteA clr ByteB clr ByteC clr ByteD clr ByteE clr ByteF cbr FlagReg,(1<