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
Lesezeichen