⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dec_t15.asm

📁 一个德国人写的基于15各采样点的dcc解码器
💻 ASM
📖 第 1 页 / 共 3 页
字号:
; ***************************************************************
; * 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 + -