- 3D-Druck Einstieg und Tipps         
Ergebnis 1 bis 2 von 2

Thema: Timingproblem !? mit Tiny13

  1. #1

    Timingproblem !? mit Tiny13

    Anzeige

    LiFePo4 Akku selber bauen - Video
    Hallo

    Es geht bei meinem Problem um einen DCC-Funktionsdecoder für die Modellbahn.

    Den ASM-Code habe ich dafür aus einem anderen Forum und er funktioniert ohne Probleme auf einem Tiny2313 mit int. Oszillator auf 8Mhz. (mit Timinganpassungen in den ISR's für gesetztes CKDIV8 funktioniert auch).

    Nun wollte ich das ganze auf einen Tiny13 umschreiben, was ja eigentlich auch geklappt hat, denke ich mir. Nur es werden keine DCC-Signale erkannt (drücken der Tasten F1-F4 auf der Roco Lokmaus2).

    Habe mir extra noch ein Testprogramm geschrieben, welches ein Port am Tiny13 oder auch Tiny2313 toggelt, um die Werte für die ISR's zu ermitteln.

    Hier mal die Initialisierung-Routine des Tiny13:
    Code:
    Reset:								; Programm Kaltstart
    	  	cli            				; alle Interrupts ausschalten
    		ldi 	temp,low(RAMEND)	; Stackpointer setzen
    		out 	SPL,temp
    
    ;		ldi		TEMP,0b01001101		;77
    ;		out		OSCCAL,TEMP
    
    ;		ldi  	temp,0b11111111		; PB als Ausgang
    ;	  	out  	DDRB,temp
    ;		clr		null				; alles auf low
    ;		out		portb,null
    		ldi 	TEMP,0b00111101		;PB0/2/3/4/5 als Ausgang, PB1 als Eingang
    	    out 	DDRB,TEMP
    		clr		null				; alles auf low
    		out		portb,null
    
    	  	ldi  	TEMP,0b00000011		; Bit0/1 ISC01 ISC00 Interupt Sense Control 0
    	  	out  	MCUCR,TEMP			; 0 0 Low Level of INT0 generate Interrupt
    									; 0 1 jeder Wechsel of INT0
    									; 1 0 die fallende Flanke of INT0
    									; 1 1 die steigende Flanke von INT0 erzeugt Interrupt
    									; Bit2/3 ISC11 ISC10 Interupt Sense Control 1
    									; wie Bit0/1
    									; Bit4 SM Sleep Modes
    									; Bit5 SE Sleep Enable
    									; Bit6/7 Reserve
    	  
    	  	ldi  	TEMP,0b01000000		; Bit0/5 Reserve
    	  	out  	GIMSK,TEMP			; Bit6 INT0 Interrupt enable
    									
    	  	ldi		TEMP,0b00000010		; Bit0 Reserve
    	  	out		TIMSK0,TEMP			; Bit1 TOIE0 Timer/Counter0 Overflow Interrupt Enable 
    									
    	  	ldi  	TEMP,0b01000000		; lösche externen Interupt 0
    	  	out 	GIFR,TEMP
    	  
    	  	ldi  	TEMP,0b00000010		; lösche Timer0 Interupt
    	  	out  	TIFR0,TEMP
    Auskommentierte Sachen nicht beachten....

    Und hier die ISR's

    Code:
    ;************************************************************************************************
    ;*						Interruptserviceroutinen												*
    ;************************************************************************************************
    ;************************************
    ;*	Eingangsinterrupt				*
    ;************************************
    ; wird bei jeder steigenden Flanke an int0/PB1 ausgelöst
    ; timer0 auf 78us vor überlauf setzen ( Highbit mind. 52us+50% )
    ; dazu teiler auf 8 (1us) 
    ; zur sicherheit überlaufintbit von timer0 noch löschen
    ; könnte ja inzwischen gesetzt sein
    
    EXT_INT0:	
    		in		intsreg,sreg		;sreg sichern
    		clr		inttemp				;timer anhalten
    		out		tccr0b,inttemp
    		ldi		inttemp,168			;Zähler setzen 
    		out		tcnt0,inttemp
    		in		inttemp,tifr0		;überlauf timer0 löschen
    		cbr		inttemp,0b00000010
    		out		tifr0,inttemp
    		sbr		flag,(1<<messen)	;für bit "messen" ein
    		cbr		flag,(1<<keindcc)	;bit für "keine befehle da" löschen
    		ldi		inttemp,0b00000001	;timer mit Teiler auf ck/8 starten
    		out		tccr0b,inttemp
    		out		sreg,intsreg		;sreg zürück
    
    ;		sbi		portb,4
    		reti						;und fertig
    
    ;************************************
    ;*		Timer_0_interrupt			*
    ;************************************
    ; wird ca 78us nach ext_int ausgelöst und liest dann bit von int0/PB1 ein
    ; danach max 10000us auf neuen ext_int warten
    ; dazu teiler auf 1024 
    
    TIM0_OVF:
    ;		cbi		portb,0		
    		in		intsreg,sreg		;sreg sichern
    		clr		inttemp				;timer anhalten
    		out		tccr0b,inttemp
    		in		inttemp,pinb		;port einlesen
    		sbrs	flag,messen			;wenn messen aktiv 1x springen
    		rjmp	warten_aktiv		;sonst gehe zu
    		com		inttemp				;port umdrehen
    		bst		inttemp,2			;bit d2 holen
    		bld		flag,bit			;und in flag bit0 sichern
    		sbr		flag,(1<<neuesbit)	;neues bit da setzen
    		cbr		flag,(1<<messen)	;flag für messen aus
    		ldi		inttemp,229			;Zähler auf 161 für tiny13 mit 9,6mhz(176 bei 2313 mit 8mhz)
    		out		tcnt0,inttemp
    		ldi		inttemp,0b00000100	;timer mit Teiler auf ck/1024 starten
    		out		tccr0b,inttemp
    		out		sreg,intsreg
    		reti
    warten_aktiv:						;ca 10000us kein bit mehr eingetroffen
    		sbr		flag,(1<<keinDCC)	;bit für keine befehle setzen
    		out		sreg,intsreg
    		reti

    Wie gesagt auf dem 2313 läuft es, nach Anpassen der Zählerwerte fürs tcnt0-Register an den entsprechenden Takt, ohne Probleme.

    Nur der Tiny13 will nicht so recht. Und der 2313 ist für den Einsatzzweck zu "übertrieben".

    Hat jemand eine Idee, was da noch falsch sein könnte ??

    Danke

  2. #2
    Benutzer Stammmitglied
    Registriert seit
    06.07.2007
    Alter
    36
    Beiträge
    81
    Ich würds mal mit debugging probieren.
    Zuerst mal den Code verstehen(wenn er nicht von dir ist), und zwar richtig!!
    Dann mal schauen was der Code im Simulator macht, vllt kann man da ja schon ein paar Fehler sehen!
    Wenn s da soweit klappt dann an bestimmten Stellen (z.B. Interrupts) eine LED oder ähnliches einschalten und schauen ob der Controller bis da hin überhaupt kommt!
    Wünsch dir viel Erfolg!!

    MFG Mixer

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

Labornetzteil AliExpress