Forum: Mikrocontroller und Digitale Elektronik Sekunde erzeugen mit Timer im CTC-Modus


von Andreas S. (andi__)


Lesenswert?

Hallo, ich habe eine Frage zur Erzeugung eines Counters, welcher jede 
Sekunde erhöht wird. Die Programmvorlage dazu haben wir von unserem 
Professor bekommen. Mikrocontroller ist ein Atmega 128, welcher mit 
Taktfrequenz 8MHz läuft

Die wichtigsten Programmteile hab ich hier:
1
unsigned char count, second;   //globale Variablen
2
3
void main(void)
4
{
5
    TCCR0= 0b00001110;  //CTC-Modus, Prescaler=256
6
    OCR0=249;            //ergibt 250 Schritte bis Interrupt auftritt
7
    TIMSK=0b00000010;   // output compare match an Timer 0 einschalten
8
    sei();
9
}
10
11
12
interrupt[16]void real_time(void)  //wird alle 8ms aufgerufen
13
{
14
   count++;
15
16
   if(count>123)
17
   {
18
      count=0;
19
      second++;  //erhöhe Variable jede Sekunde
20
   }
21
}

Der Ablauf des Programms ist mir klar. Was ich allerdings auch nach 
langem Überlegen immer noch nicht verstehe ist der Inhalt des if-Kopfes. 
Ich verstehe nicht warum es if(count>123) heißen muss, denn meiner 
Meinung muss die second-Variable nach 125 Interrupts erhöht werden und 
somit müsste der if-Kopf nach meiner Meinung if(count>124) heißen.

Wer kann mir helfen bzw. mir sagen wo mein Denkfehler liegt?

Gruß Andreas

von ich (Gast)


Lesenswert?

Andreas S. schrieb:
> Wer kann mir helfen bzw. mir sagen wo mein Denkfehler liegt?
Möglicherweise liegt der Fehler nicht bei dir. Auf den ersten Blick sehe 
ich das auch so we du: es sollte mit 124 verglichen werden.

von Andreas S. (andi__)


Lesenswert?

ich schrieb:
> Möglicherweise liegt der Fehler nicht bei dir. Auf den ersten Blick sehe
> ich das auch so we du: es sollte mit 124 verglichen werden.

Den Professor haben einige wegen der Zahl gefragt. Er schien sich mit 
der 123 ziemlich sicher und hat dann gemeint, dass wenn man ein bischen 
überlegt die Zahl schon Sinn macht. Da der Professor die Vorlesung schon 
seit vielen Jahren macht glaub ich ihm darum eigentlich schon, dass die 
Zahl 123 die Richtige ist. Die Frage ist nur warum.

Gruß Andreas

von Karl H. (kbuchegg)


Lesenswert?

Lass uns das ganze mit kleineren Zahlen probieren.

Wir wollen 5 Interrupt Aufrufe abzählen. Bei jedem 5. soll etwas 
passieren.

Variante 1 (deine und unsere)

  count++;
  if( count > 4 ) {
    count = 0;
    ...  // Aktion

count sei 3 (ich steige mitten drinnen ein um die Unsicherheit zu 
umgehen, was genau mit der allerersten 0 passiert

  count am Anfang   nach Erhöhen    nach if      Aktion
  ------------------------------------------------------
      3                4               4          Nein
      4                5               0          Ja
      0                1               1          Nein
      1                2               2          Nein
      2                3               3          Nein
      3                4               4          Nein
      4                5               0          Ja
      0                1               1          Nein
      ....

Zähl die Anzahl der Zählvorgänge von einem Ja zum nächsten.
Es sind genau 5. So wie gefordert
(Man kanns acuh so sagen: In jeder 5. Zeile steht ein 'ja'

Variante 2 (die deines Professors)

   count++;
  if( count > 3 ) {
    count = 0;
    ...


  count am Anfang   nach Erhöhen    nach if      Aktion
  ------------------------------------------------------
      3                4               0          Ja
      0                1               1          Nein
      1                2               2          Nein
      2                3               3          Nein
      3                4               0          Ja
      0                1               1          Nein
      ...

Wie man sieht vergehen von einem Ja zum nächsten nur 4 Zählvorgänge. 
D.h. Hier wird die Aktion bei jedem 4. ISR Aufruf ausgelöst.


Fazit:
Will ich n Interrupt Aufrufe abzählen und bei jedem n-ten etwas 
auslösen, dann muss es heißen
1
    count++;
2
    if( count == n ) {
3
      count = 0;
4
      ....  // Aktion
5
    }

oder eben mit >
1
    count++;
2
    if( count > (n-1) ) {
3
      count = 0;
4
      ...  // Aktion

Dein Professor hat Unrecht. Ihr liegt richtig. Da hat er was 
verwechselt.
Die Rechnung ergibt, dass für 1 Sekunde 125 ISR Aufrufe abgezählt werden 
müssen. Sein Code zählt aber nur 124 ab.


Fazit 2:
Man kann sich viele Dinge klarer machen, wenn man mit kleinen Zahlen 
einfach eine Probe macht.

von Andreas S. (andi__)


Lesenswert?

Karl Heinz Buchegger schrieb:
> Dein Professor hat Unrecht. Ihr liegt richtig. Da hat er was
> verwechselt.
> Die Rechnung ergibt, dass für 1 Sekunde 125 ISR Aufrufe abgezählt werden
> müssen. Sein Code zählt aber nur 124 ab.
>
>
> Fazit 2:
> Man kann sich viele Dinge klarer machen, wenn man mit kleinen Zahlen
> einfach eine Probe macht.

Genauso hab ich es auch ausprobiert, bzw im Kopf nachgerechnet. Gut, 
dann werd ich morgen mal direkt meinen Professor fragen bzw ihn auf 
seinen Fehler hinweisen.

Vielen Dank für eure Hilfe

von Karl H. (kbuchegg)


Lesenswert?

Andreas S. schrieb:

> Genauso hab ich es auch ausprobiert, bzw im Kopf nachgerechnet. Gut,
> dann werd ich morgen mal direkt meinen Professor fragen bzw ihn auf
> seinen Fehler hinweisen.

Aber pass auf, dass er dich nicht mit der Zählung reinlegt :-)

So ist es falsch gezählt

  count am Anfang   nach Erhöhen    nach if      Aktion     Aufruf
  ------------------------------------------------------
      3                4               0          Ja          1
      0                1               1          Nein        2
      1                2               2          Nein        3
      2                3               3          Nein        4
      3                4               0          Ja          5
      0                1               1          Nein
      ...

Wieso, sind doch 5?

Das erste 'Nein' nach dem 'Ja' kriegt die Nummer 1. (Sieht man, wenn man 
die Tabelle weiterführt.)

(Und verpack deinen Hinweis so, dass er das Gesicht wahren kann. Es ist 
nicht schlau, ihn lächerlich zu machen. Du willst was von ihm [eine gute 
Note])

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.