Forum: Mikrocontroller und Digitale Elektronik Wer kennt sich aus mit Timern???


von Andreas (Gast)


Lesenswert?

Hallo zusammen.
Ist hier evtl. jemand unter euch der mir eine Frage zum Verhalten des
8Bit Timers beantworten kann.
Und zwar: kann es sein das wenn ich z.b. vom Counter 0 das Overflow
Interrupt Enable "TOIE0" in "TIMSK" setze das dann im eigentlichen
Zählregister "TCNT0" immer null steht bzw. dieses dann nicht mit
jedem eintreffenden takt erhöht wird?? wenn ich den jenes nämlich
auslese erhalte ich immer null. Der Timer läuft aber da bin ich mir zu
100% sicher denn der int wird beim überlauf ausgelöst..
Danke im voraus ...

Grüße Andreas

von Conlost (Gast)


Lesenswert?

Hallo Andreas,

poste mal etwas Code wie du den Counter einstellst.
Hast du mal das Programm im Studio4 simuliert ?

Gruß,
Arno

von Andreas (Gast)


Lesenswert?

ich verwende den 8bit counter da ich den mit 16bit schon für andere
aufgaben brauche. ich möchte damit die zeit zwischen zwei externen
interrupts messen die höher als 256 impulse liegt.
bei eintreffen von int0 starte ich timer null mit vorteiler 8 und
aktiviere das TOIE0 bit. wenn der timer überlaüft wird in einem
unterprogramm ein zählregister z.b. count um eins erhöt das TOIE0 bit
wieder gesetzt und zurück gesprungen. wenn int0 zum zweiten mal
ausgelöst wird stoppe ich den zähler. jetzt berechne ich die dauer.
dazu multipliziere ich den inhalt vom register count (also die anzahl
der überläufe mit 0xFF) dann lese ich TCNT0 aus (was in meinem fall
leider immer null ist) und addiere es zum ergebnis dazu.
so ungefähr der ablauf.... habe schon alles probiert und wenn ich das
TOIE0 bit nicht setze dann kann aus dem TCNTO register auch was
auslesen....
ich denke mir bald das dieses problem mit der architektur des
prozessors zusammenhängt oder so

von thkais (Gast)


Lesenswert?

Falsche Definition von TCNT0 ?
Schau Dir doch mal das Listfile des Assemblers an und schau mal, womit
"TCNT0" ersetzt wird.
Ein paar nähere Angaben, z.B. welchen Controller Du benutzt und mit
welcher Sprache Du programmierst, würden uns auch etwas weniger im
Dunklen stehen lassen.

von Conlost (Gast)


Lesenswert?

@Andreas,
bist du sicher das der Timer läuft?
Hast du ihn gestartet mit beschreiben von TCCR0?

von Andreas (Gast)


Lesenswert?

Ja der Timer läuft...da bin ich mir zu 100% sicher ... verwende einen
90S8515 un dhabs auch mit 8535 probiert programmier sprache ist asm...

von Conlost (Gast)


Lesenswert?

Simuliere das doch einfach mal im Studio4, da sieht man gut was
passiert, oder besser gesagt was nicht passiert.
Ich hab es grade mal versucht und konnte TCNT0 auslesen.

von Andreas (Gast)


Lesenswert?

@Conlost

ja im studio funktioniert es aber nich in real...
hast du stk200,500? wenn du lust hast kannst du ja mal einen controller
programmieren und dir das ergebis an den led´s anzeigen lassen. ich bin
davon überzeugt das sich dort nichts tun wird...

von Frank Linde (Gast)


Lesenswert?

Zeig' doch mal Deinen Sourcecode, so ist das wirklich Fischen im
Trüben.

Gruß, Frank

von Andreas (Gast)


Lesenswert?

;*********************************************************************** 
*********
;EINSPRUNGADRESSEN
.CSEG
.ORG 0x0000
    rjmp main


.ORG 0x0001    ;externer Interrupt -0-
   rjmp extern_int0


.ORG 0x0006    ;8Bit Timer/counter0 übergelaufen
   rjmp time0_ovfl


;*********************************************************************** 
********

main:

 ;stack, ports usw. initialisieren
;----------------------
ldi reg,(RAMEND)
out SP,reg

out portc,reg
ldi reg,0x00          ;statusregister auf 0 setzen
mov status,reg

;*******************************************************
;Interrupt konfigurieren

ldi reg,0b00000010    ;fallende Flanke löst int aus
out MCUCR,reg
ldi reg,0b01000000
out GIMSK,reg         ;int0 freigeben
;ldi reg, 0b00000010
;out timsk,reg         ;Timer/counter 0,  aktivieren

*********
;interrupt freigabe
sei                   ;alle interrupts sind freigegeben



;*******************************************************
;WARTEN AUF INTERRUPT

loop:
rjmp loop






;********************************************************
;********* I N T E R R U P T _ S E K T I O N ************
;********************************************************


;********************************************************
;*************Externer-Interrupt ausgelöst***************
;********************************************************
extern_int0:
sbrc status,0      ;wenn 0 dann weiter bei inc
rjmp stop
inc status
ldi reg,0b00000010 ;Timer0 mit vorteiler 8 starten
out tccr0,reg      ;8bit Timer0 läuft
reti


stop:
clr reg

out tccr0,reg      ;8Bit Timer0 anhalten
in  test,tcnt0
out tcnt0,reg       ;Zählerregister auf 0-setzen

dec status



;********************************************************
;**************** TIMER COUNTER "0" ÜBERLAUF*************
;********************************************************
time0_ovfl:
inc  counter0
ldi reg, 0b00000010
out timsk,reg        ;Int. von Timer/counter 0  aktivieren
reti

DANN KOMMEN DIE BERECHNUNGEN


nicht wundern wegen der stackpointer initialisierung
ich verwende zur zeit ein 4433

von Conlost (Gast)


Lesenswert?

stop:
clr reg

out tccr0,reg      ;8Bit Timer0 anhalten
in  test,tcnt0
out tcnt0,reg       ;Zählerregister auf 0-setzen

dec status

Kommt hinter "dec status" noch was?
Es sieht aus als würde da ein "reti" fehlen.

von Andreas (Gast)


Lesenswert?

ja das stimmt... es ist nur ein ausschnitt von dem gesamten code.. nach
dec status kommen meine berechnungen bcd wandlung und die sende
routinen für uart usw. wenn dies erledigt ist kommt natürlich die
rücksprung anweisung "reti"
sonst siehts aber gut aus oder ??? wenn du lust hast kannst du ja mal
dein stk... oder so benutzen wenn du den timerinhalt an die led´s
ausgibst wird nichts verändern.. die beiden externen "int´s" kannst
du ja durch drücken eines tasters simulieren..

von Conlost (Gast)


Lesenswert?

So wie das Programm da steh kann es nicht gelaufen haben.

;Interrupt konfigurieren

ldi reg,0b00000010    ;fallende Flanke löst int aus
out MCUCR,reg
ldi reg,0b01000000
out GIMSK,reg         ;int0 freigeben
;ldi reg, 0b00000010   <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
;out timsk,reg  <<<<<<<<       ;Timer/counter 0,  aktivieren

*********
;interrupt freigabe
sei                   ;alle interrupts sind freigegeben

Der Timer wird hier nicht gestartet wegen dem Semikolon da <<<<<<<<.

Ausserdem ist es besser das Programm im Studio zu simulieren,
denn dort kann man sehen was in den Registern passiert.
Das kann man auf dem Board mit einer Leuchtdiode am Port nicht sehen.

Lass es mal im Studio laufen setze vor den kritischen Stellen
Breakpoints, dann kannst du mit Einzelschritt weiter machen
und dir in aller Ruhe ansehen was in den Registern steht.

Außerdem habe ich mir angewöhnt, in jeder Interruptroutine
das Statusregister zu retten, das vermeidet auch schon mal Ärger.

Versuch mal dein Glück mit Simulation im Studio.

Gruß,
Arno

von Uwe (Gast)


Lesenswert?

Hi!
Komische Sache, aber eine Idee hätte ich.

schreibe mal statt:
<stop:
<
<clr reg
<
<out tccr0,reg      ;8Bit Timer0 anhalten
<in  test,tcnt0
<out tcnt0,reg       ;Zählerregister auf 0-setzen

stop:
clr reg
in  test,tcnt0
out tccr0,reg      ;8Bit Timer0 anhalten
out tcnt0,reg       ;Zählerregister auf 0-setzen

Nicht das "out tccr0,reg      ;8Bit Timer0 anhalten"
tcnt0 löscht.

mfg Uwe

von Andreas (Gast)


Lesenswert?

an uwe..ja die idee hatte ich auch schon aber das hat nichts
gebracht..und an conlost: das mit dem semikolon hast du richtig erkannt
in meinem wirklichen code sind diese nicht vorhanden und der timer
läuft... werde mal im studio simulieren und weiter probieren

von Andreas (Gast)


Lesenswert?

so ich habs... ich habe in der "timer 0 übergelauf" routine
dem timer einfach nochmal neu gestarte und dann funktioniert..
komische sache denn normalerweise hört der counter trotz eintreffenden
int ja nicht auf zu zählen... na ist mir jetzt auch egal - bin einfach
nur froh das es funktioniert...

;********************************************************
;**************** TIMER COUNTER "0" ÜBERLAUF*************
;********************************************************
time0_ovfl:
inc  counter0

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
ldi reg,0b00000010 ;Timer0 starten          NEU NEU NEU
out tccr0,reg                               NEU NEU NEU
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
ldi reg, 0b00000010
out timsk,reg        ;Int. von Timer/counter 0  aktivieren
reti

von Conlost (Gast)


Lesenswert?

Hallo,
freut mich das es nun geht, aber du hast den Timer selber gestoppt.

<stop:
<clr reg

<out tccr0,reg      ;8Bit Timer0 anhalten
<in  test,tcnt0
<out tcnt0,reg       ;Zählerregister auf 0-setzen

<dec status

Gruß,
Arno

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.