Forum: Mikrocontroller und Digitale Elektronik Verständnis Timer aus Tutorial


von MCAnfänger (Gast)


Lesenswert?

Hallo,

ich habe eine Frage bzgl. der Interrupt Service Rouine. Ich habe den 
foglenden Code aus dem AVR-GCC-tutorial 
(http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial/Die_Timer_und_Z%C3%A4hler_des_AVR).
Hierbei soll innerhalb einer Millisekunde ein Interrupt ausgelöst 
werden. Dazu wurde ein Prescler von 8 ausgewählt und mithilfe dieser 
Vorteiler wurde der Vergleichswert von 125-1 berrechnet.
Jedoch verstehe ich nicht, was in der ISR Routine geschieht.
Danke

* uC: Attiny2313 */
#include <avr/io.h>
#include <avr/interrupt.h>

//Variablen für die Zeit
volatile unsigned int millisekunden;
volatile unsigned int sekunde;
volatile unsigned int minute;
volatile unsigned int stunde;

int main(void)
{
  // Timer 0 konfigurieren
  TCCR0A = (1<<WGM01); // CTC Modus
  TCCR0B |= (1<<CS01); // Prescaler 8
  // ((1000000/8)/1000) = 125
  OCR0A = 125-1;

  // Compare Interrupt erlauben
  TIMSK |= (1<<OCIE0A);

  // Global Interrupts aktivieren
  sei();

  while(1)
  {
    /*Hier kann die aktuelle Zeit
      ausgeben werden*/
  }
}

/*
Der Compare Interrupt Handler
wird aufgerufen, wenn
TCNT0 = OCR0A = 125-1
ist (125 Schritte), d.h. genau alle 1 ms
*/
ISR (TIMER0_COMPA_vect)
{
  millisekunden++;
  if(millisekunden == 1000)
  {
    sekunde++;
    millisekunden = 0;
    if(sekunde == 60)
    {
      minute++;
      sekunde = 0;
    }
    if(minute == 60)
    {
      stunde++;
      minute = 0;
    }
    if(stunde == 24)
    {
      stunde = 0;
    }
  }
}

von Martin S. (sirnails)


Lesenswert?

Die ISR wird alle 1ms aufgerufen. 1000ms = 1s. Die ISR zählt also nur 
Millisekunden.

von MCAnfänger (Gast)


Lesenswert?

Dass die ISR alle 1 ms aufgerufen wird, ist mir soweit klar. wie kommt 
mn auf die 1000ms=1s?

ISR (TIMER0_COMPA_vect)
{
  millisekunden++;           ----> Wo wurde diese vorher initialisiert??
  if(millisekunden == 1000)  ---->?
  {
    sekunde++;
    millisekunden = 0;
    if(sekunde == 60)
    {
      minute++;
      sekunde = 0;
    }
    if(minute == 60)
    {
      stunde++;
      minute = 0;
    }
    if(stunde == 24)
    {
      stunde = 0;
    }

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

MCAnfänger schrieb:
> millisekunden++;           ----> Wo wurde diese vorher initialisiert??

 Bei der Deklaration:
1
volatile unsigned int millisekunden;  // Wert fehlt, es wird 0 genommen
 und dann:
1
 millisekunden++;              // ++ bedeutet incr, also ms = ms + 1
2
   if(millisekunden == 1000) // Falls millisekunden gleich 1000
3
 ...

von Werner P. (Gast)


Lesenswert?

Hallo zusammen,

1
* uC: Attiny2313 */
2
#include <avr/io.h>
3
#include <avr/interrupt.h>
4
5
//Variablen für die Zeit
6
volatile uint8_t sekunde;
7
volatile uint8_t minute;
8
volatile uint8_t stunde;
9
10
int main(void)
11
{
12
  // Timer 0 konfigurieren
13
  TCCR0A = (1<<WGM01); // CTC Modus
14
  TCCR0B |= (1<<CS01); // Prescaler 8
15
  // ((1000000/8)/1000) = 125
16
  OCR0A = 125-1;
17
18
  // Compare Interrupt erlauben
19
  TIMSK |= (1<<OCIE0A);
20
21
  // Global Interrupts aktivieren
22
  sei();
23
24
  while(1)
25
  {
26
    /*Hier kann die aktuelle Zeit
27
      ausgeben werden*/
28
  }
29
}
30
31
/*
32
Der Compare Interrupt Handler
33
wird aufgerufen, wenn
34
TCNT0 = OCR0A = 125-1
35
ist (125 Schritte), d.h. genau alle 1 ms
36
*/
37
ISR (TIMER0_COMPA_vect)
38
{
39
  static unsigned int millisecunden = 0;
40
41
  millisekunden++;
42
  if(millisekunden == 1000)
43
  {
44
    sekunde++;
45
    millisekunden = 0;
46
    if(sekunde == 60)
47
    {
48
      minute++;
49
      sekunde = 0;
50
    }
51
    if(minute == 60)
52
    {
53
      stunde++;
54
      minute = 0;
55
    }
56
    if(stunde == 24)
57
    {
58
      stunde = 0;
59
    }
60
  }
61
}

Ist es nicht besser die millisekunden in der ISR als static zu 
deklarieren und bei den variablen sekunde, minute und stunde anstelle 
von unsigned int uint8_t zu verwenden?

von KeineZeit (Gast)


Lesenswert?

Sekunden einmal mit 'k' und einmal mit 'c'?

von Dennis S. (eltio)


Lesenswert?

Werner P. schrieb:
> Ist es nicht besser die millisekunden in der ISR als static zu
> deklarieren

"Besser" ist immer vom Kontext abhängig. Wenn du die Millisekungen in 
deiner Main haben willst sollte sie dort eben auch verfügbar sein.. wenn 
nicht dann nicht.

> und bei den variablen sekunde, minute und stunde anstelle
> von unsigned int uint8_t zu verwenden?
Kann man machen.

Gruß
Dennis

von Ingo L. (corrtexx)


Lesenswert?

Werner P. schrieb:
> Ist es nicht besser...
Ist es, es sei denn du benötigst die Millisekunden auch außerhalb.
Ich hätte es auch mit uint8_t gemacht. Auch die if-Abfragen kann man 
geschickter lösen:
1
if (++millis == 1000){
2
  millis = 0;
3
  if ( ++Sekunden == 60 ){
4
    Sekunden = 0;
5
    if ( ++Minuten == 60 ){
6
      Minuten = 0;
7
      if ( ++Stunden == 24 ){
8
        Stunden = 0;
9
      }
10
    }
11
  }
12
}
So werden die if-Abfragen wirklich nur abgefragt, wenn sich was geändert 
haben kann.

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.