📄 dec_t15.asm
字号:
; ***************************************************************
; * Copyright by mad.dax@t-online.de *
; * DCC-Decoder Testversion *
; * 14 / 28 und 126 Fahrstufen ( Fahrstufe 14 = 27 ) *
; * 躡erg鋘ge Stufenlos *
; * PWM mit 6125 HZ, internes Timing mit CV6 trimmbar *
; * kurze und lange Adressierung ( 7 und 14 Bit je nach CV ) *
; * F1 / F2 als Ausg鋘ge, F3 als Rangiergang *
; * Mehrfachtraktion ( Consist ) noch nicht getestet *
; * Programming on the Track mit DDW-Server V 0.6.7 und *
; * Java DCC Railroad Network Client V 4.11 getestet *
; * Bedienung auch mit GPlan V 0.60 getestet *
; * Version: 06.04 *
; ***************************************************************
;
; 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點kw鋜ts
; GND = 4 5 = PB0 Ausgang Vorw鋜ts
;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鋜ts, 0=r點kw鋜ts
.equ FL =4 ;FL nicht benutzt
.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鋘ge = 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鰃erungskonstante im EEPROM
.equ EEMaxSpeed = 4 ;Speicherplatz H鯿hstgeschwindigkeit 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 Adresse = R0 ;eigene Adresse
.def ISTSpeed = R1 ;berechnete Geschwindigkeit
.def SOLLSpeed = R2 ;Soll Geschwindigkeit
.def IncCnt = R3 ;Beschleunigungsz鋒ler/Bremsz鋒ler
.def IncVAL = R4 ;Beschleunigungkonstante
.def IncCnt1 = R5 ;Beschleunigungsz鋒ler/Bremsz鋒ler
.def DecVAL = R6 ;Bremskonstante
.def MaxSpeed = R7 ;H鯿hstgeschwindigkeit
.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黵 lange Adresse
.def LoAdresse = R15 ;eigene Adresse Lo-Byte f黵 lange Adresse
.def TEMPS = R16 ;SREG Sicherungsregister
.def TEMPI = R17 ;TEMP Register f黵 Initialisierung und Interupt-Schmierregister
.def TEMP1 = R18 ;TEMP Register f黵 Hauptprogramm und Initialisierung
.def TEMP2 = R19 ;TEMP Register f黵 Hauptprogramm
.def TEMP3 = R20 ;TEMP Register f黵 Hauptprogramm
.def CONAdr = R21 ;Consist-Adresse ( Mehrfachtraktion )
;def FREI = R22
.def FlagReg = R23 ;Flag Register
.def DCCReg = R24 ;DCC Register f黵 Funktionen und Fahrtrichtung
.def ByteCNT = R25 ;Bytez鋒ler f黵 Datenhandling
.def BitCNT = R26 ;Bitz鋒ler f黵 Datenhandling
.def PRGCHECK = R27 ;Checkbyte f黵 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 ;PIN_CHANGE ; Pin change handler
reti ;TIM1_CMP ; Timer1 compare match
rjmp TIM1_OVF ; Timer1 overflow handler
rjmp TIM0_OVF ; Timer0 overflow handler
reti ;EE_RDY ; EEPROM Ready handler
reti ;ANA_COMP ; Analog Comparator handler
reti ;ADC ; ADC Conversion Handler
;
;
; **************** Ende der Interrupt Service Routinen *********************
;
;
; 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點ksprung
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點ksprung
EXT_INT0: ;Flankenwechsel 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鰏che Timer 0 Interrupt Flag
andi TEMPI,0b00000010 ; das eventuell w鋒rend dieses Interuptaufrufes
out TIFR,TEMPI ; gesetzt worden ist
cbr FlagReg, (1<<LoTiF)+(1<<BitNew); l鰏che Long Time Flag f黵 Zeit黚erschreitung
; l鰏che indikator f黵 neues Bit
ldi TEMPI, SampleTime; lade das Timer/Counter0
out TCNT0,TEMPI ; mit der Zeit fuer 'Abtasten
ldi TEMPI,0b00000001 ; 0 0 0 Stop, the Timer/Counter0 is stopped.
out TCCR0,TEMPI ; 0 0 1 CK
; 0 1 0 CK/8
; 0 1 1 CK/64
; 1 0 0 CK/256
; 1 0 1 CK/1024
; 1 1 0 External Pin T0, falling edge
; 1 1 1 External Pin T0, rising edge
out SREG,TEMPS ; SREG r點ksichern
reti ; R點ksprung und Interupts wieder einschalten
TIM1_OVF: ;Beschleunigungs/Verz鰃erungsz鋒ler
;bei Timer 1 = 1,6 MHz wird der
;Interupt wid demnach alle 6250 Hz ausgel鰏t
;die k黵zeste Rampen-Zeit ist 0,12 Sec f黵 den Sprung von 0 auf 252 bei IncVAL = 0
;die l鋘gste Rampen-Zeit ist 31,3 sec f黵 den Sprung von 0 auf 252 bei IncVAL = 255
ldi TEMPI, 3 ; Verz鰃erungsfaktor
inc IncCNT1 ; erh鰄e Z鋒ler
cp IncCNT1, TEMPI
brne OVF1
clr IncCNT1 ; l鰏che Beschleunigungsz鋒ler
inc IncCNT
cp ISTSpeed, SOLLSpeed; vergleiche IST <> SOLL
breq Gleich ; wenn Wert nicht gleich
brsh DECSpeed ; wenn Wert gr鲞er gleich
brlo INCSpeed ; wenn Wert kleiner
Gleich: clr IncCNT ; l鰏che Beschleunigungsz鋒ler
clr IncCNT1 ; l鰏che Beschleunigungsz鋒ler
reti ; R點ksprung und Interupts wieder einschalten
INCSpeed: cp IncCNT, IncVAL ; vergleiche Beschleunigungsz鋒ler
brne OVF1 ; Springe wenn kleiner
clr IncCNT ; l鰏che Beschleunigungsz鋒ler
clr IncCNT1 ; l鰏che Beschleunigungsz鋒ler
inc ISTSpeed ; erh鰄e Speed
rjmp PWMOut ; weiter
DECSpeed: cp IncCNT, DECVAL ; vergleiche Beschleunigungsz鋒ler
brne OVF1 ; Springe wenn kleiner
clr IncCNT ; l鰏che Beschleunigungsz鋒ler
clr IncCNT1 ; l鰏che Beschleunigungsz鋒ler
dec ISTSpeed ; verringere Speed
PWMOut: tst ISTSpeed ; ist Speed 0
brne OUT ; dann 0 ansonsten Out
ldi TEMPI,0b01000101 ; Timer/Counter1 PWM vom
out TCCR1,TEMPI ; Ausgang trennen
cbi PortB, PB0 ; alles auf Null
reti ; R點ksprung und Interupts wieder einschalten
OUT: sbrs DCCReg, DIR ; wenn Fahrtrichtung vorw鋜ts
rjmp REV ; 黚erspringe setzen Ausgang r點kw鋜ts
cbi PORTB, PB0 ; setze Ausgang f黵 vorw鋜ts
out OCR1A, ISTSpeed ; Wert f黵 Speed nach Timer 1 Compare
ldi TEMPI,0b01100101 ; Timer/Counter1 PWM
out TCCR1,TEMPI ; Ausgang direkt
reti ; R點ksprung und Interupts wieder einschalten
REV: sbi PORTB, PB0 ; setze Ausgang f黵 r點kw鋜ts
out OCR1A, ISTSpeed ; Wert f黵 Speed nach Timer 1 Compare
ldi TEMPI,0b01110101 ; Timer/Counter1 PWM
out TCCR1,TEMPI ; Ausgang indirekt
OVF1: reti ; R點ksprung 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<<LoTiF)+(1<<BitNew); l鰏che Long Time Flag f黵 Zeit黚erschreitung
; l鰏che indikator f黵 neues Bit
out SREG,TEMPS ; SREG r點ksichern
reti ; R點ksprung und Interupts wieder einschalten
SAMPLE: in TEMPI, PINB ; hole PORT B
com TEMPI ; drehe PORT B
bst TEMPI, PB2 ; hole Eingangswert
bld FlagReg, Bit ; nach Merker
sbr FlagReg, (1<<BitNew)+(1<<LoTiF); und signalisiere neues Bit angekommen
; setze Long Time Flag f黵 Zeit黚erschreitung
ldi TEMPI,WaitTime ; lade das Timer/Counter0
out TCNT0,TEMPI ; mit der Zeit fuer Warten
ldi TEMPI,0b00000011 ; 0 0 0 Stop, the Timer/Counter0 is stopped.
out TCCR0,TEMPI ; 0 0 1 CK
; 0 1 0 CK/8
; 0 1 1 CK/64
; 1 0 0 CK/256
; 1 0 1 CK/1024
; 1 1 0 External Pin T0, falling edge
; 1 1 1 External Pin T0, rising edge
out SREG,TEMPS ; SREG r點ksichern
reti ; R點ksprung und Interupts wieder einschalten
;BITFILTER:;Bitfilter
;clr BitCnt ;
;clr Temp1 ;
;sec ; setzte Carry
;rol Temp1 ; schiebe Carry von rechts in das Register
;BITFIL: cp BitCnt, Temp3 ; vergleiche mit Bitposition
;breq BITFILEND ; und springe wenn Bit auf Position
;rol Temp1 ; schiebe Carry von rechts in das Register
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -