Forum: Mikrocontroller und Digitale Elektronik Frage zum Timer/Counter


von Frank (Gast)


Lesenswert?

Hallo an alle,


ich habe mir das Tutorial durchgelesen auch zum Timer/Counter.

Jetzt meine Frage: kann man den Timer/Counter NULLEN? Der T/C wird ja 
automatisch beim Überlauf auf NULL gesetzt, ich möchte den Timer/Counter 
aber selber NULLEN.

Und dann gibt es da die Funktion den T/C zu stoppen, wird damit auch 
automatisch der T/C genullt??


mfg Frank

von ecslowhand (Gast)


Lesenswert?

Ja, Timer stoppen und Timer-Counterregister löschen.

von Johannes M. (johnny-m)


Lesenswert?

Frank wrote:
> Jetzt meine Frage: kann man den Timer/Counter NULLEN? Der T/C wird ja
> automatisch beim Überlauf auf NULL gesetzt, ich möchte den Timer/Counter
> aber selber NULLEN.
Einfach in das Zählregister 0 reinschreiben. Aber Achtung: Der Prescaler 
wird dadurch nicht zurückgesetzt! Bei einigen AVRs gibt es ein 
Prescaler-Reset-Bit (z.B. beim Mega48/88/168 das PSRSYNC im Register 
GTCCR, beim Mega8 und Mega16 PSR10 und PSR2 im SFIOR), mit dem man den 
Prescaler ebenfalls zurücksetzen kann (drauf achten, das sich manche 
Timer, z.B. Timer 0 und 1 beim Mega8/16 einen Prescaler teilen!).

> Und dann gibt es da die Funktion den T/C zu stoppen, wird damit auch
> automatisch der T/C genullt??
Nein, er wird dabei nicht zurückgesetzt.

von Frank (Gast)


Lesenswert?

Hey Danke für die schnelle Antwort, leider hatte ich zwei fragen 
gestellt... auf was bezieht sich jetzt dein ja?


mfg frank

von ecslowhand (Gast)


Lesenswert?

Johannes M. antwort erläutert Dir Deine beiden Fragen.

von Frank (Gast)


Lesenswert?

Jawoll Danke, es funktioniert :-)


Jetzt aber noch ne Frage. Mein Quelltext sieht folgendermaßen aus:

//*** INTERRUPT-Routine Flankenwechsel ***//

ISR (TIMER1_CAPT_vect)   {


  if (timer_f[0]==0)
  {
    timer_f[0] = ICR1;
    TCCR1B &= ~(1<<ICES1);
    TIFR |= (1<<ICF1);
  }

  else
  {
    timer_f[1] = ICR1;
    TCCR1B |= (1<<ICES1);
    TIFR |= (1<<ICF1);
    TCNT1 = 0;
  }
}


und in der Hauptschleife:

  if ((timer_f[0] != 0) && (timer_f[1] != 0))
    {
      timer = timer_f[0]-timer_f[1];
      zeit=timer;

      _delay_ms(10000);
      timer_f[0] = 0, timer_f[1] = 0, timer = 0;
    }


Meine Frage lautet: zählt der Timer standardmäßig von oben(65536) auf 
Null(0) oder umgekehrt??

ich habe nämlich nen Problem mit folgender Zeile:

timer = timer_f[0]-timer_f[1];

heißt ich Subtrahiere vom eigentlich niedrigeren Wert(denke ich 
zumindest)
den höheren Wert, damit müsste immer ein negativer Wert bei rauskommen, 
es kommt aber genau der wert raus den ich benötige...


mfg Frank

von Karl H. (kbuchegg)


Lesenswert?

> Meine Frage lautet: zählt der Timer standardmäßig von oben(65536) auf
> Null(0) oder umgekehrt??
Er zählt hoch.


* Welchen Datentyp hat timer_f?
* Bist du sicher, dass kein Timer Overflow während des
  Capturens passiert?
* Hast du dir die timer_f Werte schon mal einzeln angesehen?

Weiters:
* Was wird wohl passieren, wenn während der Berechnung
   timer = timer_f[0]-timer_f[1];
  Der Capture Interrupt zuschlägt und dir die Werte unter dem A....
  umdreht.

von Frank (Gast)


Lesenswert?

* Welchen Datentyp hat timer_f?

--> unsigned long int also 16-Bit

* Bist du sicher, dass kein Timer Overflow während des
  Capturens passiert?

eigentlich schon, da ich den wert ja wieder auf Null setze...
wäre es sinnvoller den timer zu stoppen?

* Hast du dir die timer_f Werte schon mal einzeln angesehen?
nein


Weiters:
* Was wird wohl passieren, wenn während der Berechnung
   timer = timer_f[0]-timer_f[1];
  Der Capture Interrupt zuschlägt und dir die Werte unter dem A....
  umdreht.

hab vor die berechnung ein cli(); geknallt und dahinter wieder ein 
sei();

mfg frank

von Karl H. (kbuchegg)


Lesenswert?

Frank wrote:
> * Welchen Datentyp hat timer_f?
>
> --> unsigned long int also 16-Bit

gut. Das unsigned wollte ich sehen.

>
> * Bist du sicher, dass kein Timer Overflow während des
>   Capturens passiert?
>
> eigentlich schon, da ich den wert ja wieder auf Null setze...
> wäre es sinnvoller den timer zu stoppen?

Das ist nicht dasselbe.
Dein erster ICP Interrupt kommt. Du merkst dir den Wert.
Der Timer zählt weiter. Und zählt und zählt und zählt.
Irgendwann läuft der Timer über und beginnt wieder bei 0.
Und zählt und zählt.
Und erst jetzt kommt dein zweiter ICP.

>
> * Hast du dir die timer_f Werte schon mal einzeln angesehen?
> nein

mach das mal

von Frank (Gast)


Lesenswert?

hab ich gemacht chef,


folgendes kommt raus erster wert immer bei etwa 8182
der zweite ist da schon ungenauer... liegt aber im dreh um die 1600 
zählzeiten höher was bei 16 MHz ja genau meinen 100us breiten Flanken 
entspricht die ich auf den Controller gebe!


mfg Frank

von Karl H. (kbuchegg)


Lesenswert?

Frank wrote:
> hab ich gemacht chef,
>
>
> folgendes kommt raus erster wert immer bei etwa 8182
> der zweite ist da schon ungenauer... liegt aber im dreh um die 1600
> zählzeiten höher was bei 16 MHz ja genau meinen 100us breiten Flanken
> entspricht die ich auf den Controller gebe!

ok.
Also ist timer_f[0] ~ 8000
         timer_f[1] ~ 9600

Die Variablen timer und zeit sind ebenfalls unsigned?

Hmm, das ist das ein bischen mysteriös, warum bei

     timer_f[0] - timer_f[1]

ein Wert von um die 1600 rauskommt.
Schau dir mal alle beteiligten Variablen an. Vielleicht schafft
das etwas Licht ins Dunkel.

von Frank (Gast)


Lesenswert?

Hallo Karl Heinz,

danke für deine Mühe, jetzt läufts sauber.
Habe die Interrupts clever gesperrt den timer gestoppt und dann den 
Zähler auf Null gesetzt.

Damit kann ich jetzt richtig geil Pulsweiten einlesen... bis zu 4us 
genau, darunter hakts an der Frequenz, werd ich mal noch schnell was zu 
schreiben.


mfg Frank

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.