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

📄 dec_t15.asm

📁 一个德国人写的基于15各采样点的dcc解码器
💻 ASM
📖 第 1 页 / 共 3 页
字号:
	  ;inc BitCnt		; erh鰄e Z鋒ler
	  ;rjmp BITFIL	  	; Schleife
;BITFILEND:ret                  	; R點ksprung


;BITSETZEN:;Bit-Wert holen	
	  ;clr BitCnt		; 
	  ;clr Temp1		;
	  ;sec			; setzte Carry
	  ;sbrs ByteC, 3		; wenn empfangenes Bit=1
	  ;clc			; sonst l鰏che Carry
	  ;rol Temp1 		; schiebe Carry von rechts in das Register
;BITSET:	  cp  BitCnt, Temp3	; vergleiche mit Bitposition
	  ;breq BITSETEND	; und springe wenn Bit auf Position
	  ;rol Temp1		; schiebe Carry von rechts in das Register
	  ;inc BitCnt		; erh鰄e Z鋒ler
	  ;rjmp BITSET	  	; Schleife
;BITSETEND:ret                  	; R點ksprung

RUN:	; Timer und Interupts mit RUN-Werten laden

	  ldi  TEMP1,0b00000110	;Timer 0/1 Overflow enable
	  out  TIMSK,TEMP1
	  
	  ldi  TEMP1,0b11111100	; Timer/Counter1 PWM
          out  OCR1B,TEMP1	; OCR1B mit 252
          
	  ldi  TEMP1,0b01000101	; 0 0 0 0 Timer/Counter1 is stopped.
          out  TCCR1,TEMP1	; 0 0 0 1 CK*16 (=PCK)
                     		; 0 0 1 0 CK*8 (=PCK/2)
				; 0 0 1 1 CK*4 (=PCK/4)
				; 0 1 0 0 CK*2 (=PCK/8)
				; 0 1 0 1 CK f黵 PWM mit 6125 Hz
				; 0 1 1 0 CK/2
				; 0 1 1 1 CK/4
				; 1 0 0 0 CK/8 
				; 1 0 0 1 CK/16
				; 1 0 1 0 CK/32
				; 1 0 1 1 CK/64
				; 1 1 0 0 CK/128 
				; 1 1 0 1 CK/256
				; 1 1 1 0 CK/512
				; 1 1 1 1 CK/1024
	  clr TEMP1
          out TCNT1,TEMP1	; l鰏che Timer 1 
          
          ldi  TEMP1,0b00000110	; l鰏che Timer Interupts
	  out  TIFR,TEMP1
	  
	  cbr  Flagreg, (1<<SERVMODE); beende Servicemode
	  
	  rjmp MAIN		; Endlosschleife				
	  

RESET: 	; Programm Kaltstart
	  cli            	; alle Interrupts ausschalten
	  
	  ldi  TEMP1,0b01000011	;Interupt auf Rise-Flanke, Pull-Up Disabble
	  out  MCUCR,TEMP1
	  
	  ldi  TEMP1,0b01000000	;Interupt 0 enable
	  out  GIMSK,TEMP1
	  
	  ldi  TEMP1,0b00000010	;Timer 0 Overflow enable
	  out  TIMSK,TEMP1
	  
	  ldi  TEMP1,0b00011011	;PB0/1/3/4 als Ausgang, PB2/5 als Eingang
	  out  DDRB,TEMP1
	  
	  ldi TEMP1, EEOSCCAL	;hole Oszillator Calibrierung
	  rcall readEEProm
	  out OSCCAL, Temp2
	  
	  ldi TEMP1, EEAdresse	;hole Adresse
	  rcall readEEProm
	  mov Adresse, Temp2
	  
	  ldi TEMP1, EEIncrease	;hole Beschleunigung
	  rcall readEEProm
	  mov IncVAL, Temp2
	  
	  ldi TEMP1, EEDecrease	;hole Verz鰃erung
	  rcall readEEProm
	  mov DecVAL, Temp2
	  
	  ldi TEMP1, EEMaxSpeed	;hole H鯿hstgeschwindigkeit
	  rcall readEEProm
	  mov MaxSpeed, Temp2
	  
	  ldi TEMP1, EELongADR	; Bit f黵 Lange Adresse 
	  rcall readEEProm
	  bst Temp2, 5
	  bld DCCReg, LongADR
	  bst Temp2, 0		; Reversierbetrieb
	  bld DCCReg, RevDir
	  
	  ldi TEMP1, EELongADRHI; Lange Adresse 
	  rcall readEEProm
	  mov HIAdresse, Temp2    
	  
	  ldi TEMP1, EELongADRLO; Lange Adresse 
	  rcall readEEProm
	  mov LOAdresse, Temp2
	  
	  ldi TEMP1, EECONAdr	; Consist Adresse 
	  rcall readEEProm
	  mov CONAdr, Temp2
	  bst CONAdr, 7		; hole Consist Richtung
	  bld FlagReg, CONREV
	  andi CONAdr, 0b01111111; blende Richtung in Adresse aus 
	  
	  ldi  TEMP1,0b00001100	; 0 0 0 0 Timer/Counter1 is stopped.
          out  TCCR1,TEMP1	; 0 0 0 1 CK*16 (=PCK)
                     		; 0 0 1 0 CK*8 (=PCK/2)
				; 0 0 1 1 CK*4 (=PCK/4)
				; 0 1 0 0 CK*2 (=PCK/8)
				; 0 1 0 1 CK
				; 0 1 1 0 CK/2
				; 0 1 1 1 CK/4
				; 1 0 0 0 CK/8 
				; 1 0 0 1 CK/16
				; 1 0 1 0 CK/32
				; 1 0 1 1 CK/64
				; 1 1 0 0 CK/128 f黵 Resetzeit und ACK
				; 1 1 0 1 CK/256
				; 1 1 1 0 CK/512
				; 1 1 1 1 CK/1024
	  
	  ldi  TEMP1, RESTime   ; lade das Timer/Counter1 
          out  TCNT1, TEMP1	; mit der Zeit fuer Reset
          
	  ldi  TEMP1,0b01000000	; l鰏che externen Interupt 0
	  out  GIFR,TEMP1
	  
	  ldi  TEMP1,0b00000110	; l鰏che Timer Interupts
	  out  TIFR,TEMP1
	    	  
	  ; bereinige alle ben鰐igten Register	  
	  clr ISTSpeed
	  clr SOLLSpeed
	  clr IncCnt
	  clr IncCnt1
	  andi DCCReg, 0b11000000
	  clr TEMP1
	  out PortB, TEMP1
	  sbr Flagreg, (1<<SERVMODE) ; setze Service	  
	  sei 			; aktiviere alle gesetzten Interupts 
				
				
Main: ;hier beginnt das Hauptprogramm
	  
	  clr  BitCnt       	; nein, dann loesche den BitCounter wieder
          clr  ByteA		; loesche die Empfangsregister wieder
          clr  ByteB
          clr  ByteC
          clr  ByteD
          clr  ByteE
          clr  ByteF
          cbr  FlagReg, (1<<BitNew)+(1<<Bit)+(1<<LoTif)      
  	
PREAMBLE: ; Pr黤e Pr鋋mbel nach NMRA-DCC
	  sbrs FlagReg, BitNew	; wenn kein neues Bit dann
	  rjmp PC-1		; Schleife
	  cbr FlagReg,(1<<BitNew); l鰏che indikator f黵 neues Bit
	  sbrs FlagReg, Bit	; wenn Bit = 1 dann erh鰄e Z鋒ler
	  rjmp PreEND		; ansonsten Signal f黵 Pr鋋mbel Ende
	  inc BitCnt		;
	  rjmp PREAMBLE		; Schleife

PreEND:   cpi BitCnt, 10	; wenn Bitz鋒ler kleiner 10
	  brlo PreFehl		; dann Fehler		  
	  clr BitCnt		; l鰏che Z鋒ler
	  rjmp GetByteA  	; hole Adresse (kurze NMRA-Adresse )
 
PreFehl:  rjmp MAIN		; Endlosschleife


GetByteA: ; hole erstes von bis zu sechs Bytes
	  
	  sbrs FlagReg, BitNew	; wenn kein neues Bit dann
	  rjmp PC-1		; Schleife
	  cbr FlagReg,(1<<BitNew); l鰏che indikator f黵 neues Bit
	  cpi BitCnt, 8		; vergleiche mit Bytel鋘ge		;
	  breq ByteAENDE	; und springe wenn Byte eingelesen
	  sec			; setzte Carry
	  sbrs FlagReg, Bit	; wenn empfangenes Bit=1 
	  clc			; l鰏che Carry
	  rol ByteA		; schiebe Carry von rechts in das Register
	  inc BitCnt		; erh鰄e Z鋒ler
	  rjmp GetByteA	  	; Schleife
	 
ByteAENDE:mov Temp1, ByteA	; sichere Byte
	  sbrc FlagReg, Bit	; wenn empfangenes Bit=1 
	  rjmp MAIN		; dann Byte nicht korrekt abgeschlossen
	  clr BitCnt		; l鰏che Z鋒ler
	  
GetByteB: ; hole zweites von bis zu sechs Bytes
	  
	  sbrs FlagReg, BitNew	; wenn kein neues Bit dann
	  rjmp PC-1		; Schleife
	  cbr FlagReg,(1<<BitNew); l鰏che indikator f黵 neues Bit
	  cpi BitCnt, 8		; vergleiche mit Bytel鋘ge		;
	  breq ByteBENDE	; und springe wenn Byte eingelesen
	  sec			; setzte Carry
	  sbrs FlagReg, Bit	; wenn empfangenes Bit=1 
	  clc			; l鰏che Carry
	  rol ByteB		; schiebe Carry von rechts in das Register
	  inc BitCnt		; erh鰄e Z鋒ler
	  rjmp GetByteB	  	; Schleife
	 
ByteBENDE:eor TEMP1, ByteB	; bilde XOR	
	  sbrc FlagReg, Bit	; wenn empfangenes Bit=1 
	  rjmp MAIN		; dann Byte nicht korrekt abgeschlossen
	  clr BitCnt		; l鰏che Z鋒ler

GetByteC: ; hole drittes von bis zu sechs Bytes
	  
	  sbrs FlagReg, BitNew	; wenn kein neues Bit dann
	  rjmp PC-1		; Schleife
	  cbr FlagReg,(1<<BitNew); l鰏che indikator f黵 neues Bit
	  cpi BitCnt, 8		; vergleiche mit Bytel鋘ge		;
	  breq ByteCENDE	; und springe wenn Byte eingelesen
	  sec			; setzte Carry
	  sbrs FlagReg, Bit	; wenn empfangenes Bit=1 
	  clc			; l鰏che Carry
	  rol ByteC		; schiebe Carry von rechts in das Register
	  inc BitCnt		; erh鰄e Z鋒ler
	  rjmp GetByteC	  	; Schleife
	 
ByteCENDE:eor TEMP1, ByteC	; bilde XOR
	  sbrc FlagReg, Bit	; wenn empfangenes Bit=1 
	  rjmp Check		; dann Telegrammende
	  clr BitCnt		; l鰏che Z鋒ler
	  
GetByteD: ; hole viertes von bis zu sechs Bytes
	  
	  sbrs FlagReg, BitNew	; wenn kein neues Bit dann
	  rjmp PC-1		; Schleife
	  cbr FlagReg,(1<<BitNew); l鰏che indikator f黵 neues Bit
	  cpi BitCnt, 8		; vergleiche mit Bytel鋘ge		;
	  breq ByteDENDE	; und springe wenn Byte eingelesen
	  sec			; setzte Carry
	  sbrs FlagReg, Bit	; wenn empfangenes Bit=1 
	  clc			; l鰏che Carry
	  rol ByteD		; schiebe Carry von rechts in das Register
	  inc BitCnt		; erh鰄e Z鋒ler
	  rjmp GetByteD	  	; Schleife
	 
ByteDENDE:eor TEMP1, ByteD	; bilde XOR
	  sbrc FlagReg, Bit	; wenn empfangenes Bit=1 
	  rjmp Check		; dann Telegrammende
	  clr BitCnt		; l鰏che Z鋒ler
	  
GetByteE: ; hole f黱ftes von bis zu sechs Bytes
	  
	  sbrs FlagReg, BitNew	; wenn kein neues Bit dann
	  rjmp PC-1		; Schleife
	  cbr FlagReg,(1<<BitNew); l鰏che indikator f黵 neues Bit
	  cpi BitCnt, 8		; vergleiche mit Bytel鋘ge		;
	  breq ByteEENDE	; und springe wenn Byte eingelesen
	  sec			; setzte Carry
	  sbrs FlagReg, Bit	; wenn empfangenes Bit=1 
	  clc			; l鰏che Carry
	  rol ByteE		; schiebe Carry von rechts in das Register
	  inc BitCnt		; erh鰄e Z鋒ler
	  rjmp GetByteE	  	; Schleife
	 
ByteEENDE:eor TEMP1, ByteE	; bilde XOR
	  sbrc FlagReg, Bit	; wenn empfangenes Bit=1 
	  rjmp Check		; dann Telegrammende
	  clr BitCnt		; l鰏che Z鋒ler
	  
GetByteF: ; hole sechstes Byte
	  
	  sbrs FlagReg, BitNew	; wenn kein neues Bit dann
	  rjmp PC-1		; Schleife
	  cbr FlagReg,(1<<BitNew); l鰏che indikator f黵 neues Bit
	  cpi BitCnt, 8		; vergleiche mit Bytel鋘ge		;
	  breq ByteFENDE	; und springe wenn Byte eingelesen
	  sec			; setzte Carry
	  sbrs FlagReg, Bit	; wenn empfangenes Bit=1 
	  clc			; l鰏che Carry
	  rol ByteF		; schiebe Carry von rechts in das Register
	  inc BitCnt		; erh鰄e Z鋒ler
	  rjmp GetByteF	  	; Schleife
	 
ByteFENDE:eor TEMP1, ByteF	; bilde XOR
	  sbrs FlagReg, Bit	; wenn empfangenes Bit=0 
	  rjmp MAIN		; dann Byte nicht korrekt abgeschlossen	  		  	  	  	  	  	  	  	  
	 	  
Check:    ; Datenpr黤ung und 躡ergabe	    	  	    	    	  	    	  
	  
	  tst TEMP1		; pr黤e auf 0			 	 
	  brne CHECKFehl	; wenn nicht 0 dann Fehler
	  
	  sbrc Flagreg, SERVMODE
	  rjmp Servicemode; Programmiermodus CV-Lesen, Schreiben, Bitmanipulation
	  
	  ldi TEMP1, 0 		; pr黤e Adresse
	  cp ByteA, TEMP1	; wenn 0 dann 
	  breq CHECKALL		; Broadcast an alle
	  
	  ldi TEMP1, 255	; pr黤e Adresse
	  cp ByteA, TEMP1	; wenn 255 dann
	  breq CHECKIDLE	; IDLE an alle
	  
	  tst CONAdr		; pr黤e Consist-Adresse ( Mehrfachtraktion ) auf NULL
	  brne CONCHECK		; und springe wenn gesetzt
	  sbrc DCCReg, LongADR	; wenn Bit gesetzt 
	  rjmp CHECKLONG	; lange Adresse
	  cp  Adresse, ByteA	; wenn eigene Adresse
	  breq CHECKEND		; dann Check OK
	  	  
CHECKIDLE:; alle Decoder sind IDLE
	  	  
CHECKFehl:;Pr黤summenfehler
	  rjmp MAIN		; Endlosschleife

CONCHECK: ;Pr黤ung auf Consistadresse	  
	  
	  mov TEMP1, ByteA	; sichere Daten
	  andi TEMP1, 0b01111111; blende Bit 7 aus
	  cp  CONAdr, TEMP1	; wenn eigene Consist-Adresse
	  breq CHECKEND		; dann Check OK
	  rjmp MAIN		; Endlosschleife
	  

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -