Timer zählt zu langsam

OP #1506481
Lesenswert?

Abend zusammen,

ich schmore gerade über folgendem Code:
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
#include <util/delay.h>
4
#include "lcd-routines.h"
5
#include <stdlib.h>
6

7
 
8
//Variablen für die Zeit
9
volatile unsigned int  millisekunden=0;
10
volatile unsigned int  sekunde=0;
11

12
int main(void)
13
{
14
  TCCR2 =(1<<WGM21) | (1<<CS00) | (1<<CS01);    //Prescaler 64 / OCR0 125: 8MHz:64:125 = 1KHz
15
  OCR2=125;
16
  TIMSK|=(1<<OCIE2);
17
  sei();                          //3)Interrupts aktivieren
18

19
   while(1)
20
   {
21
   }
22
 
23
   return 0;
24
}
25
 
26
ISR (TIMER2_COMP_vect)              //4)Führe diese ISR bei Overflow von TCNT0 aus
27
{
28
  millisekunden++;
29
  if (millisekunden == 1000)
30
  {
31
    sekunde ++;
32
    millisekunden = 0;
33
  }
34
  // ... umwandeln siehe FAQ Artikel bei www.mikrocontroller.net
35
  // WinAVR hat eine itoa()-Funktion, das erfordert obiges #include <stdlib.h>
36
  char Buffer_ms[20]; // in diesem {} lokal
37
  itoa( millisekunden, Buffer_ms, 10 ); 
38
  // ... ausgeben 
39
  char Buffer_s[20]; // in diesem {} lokal
40
  itoa( sekunde, Buffer_s, 10 ); 
41
  // ... ausgeben 
42
  lcd_init();
43
  set_cursor(7,1);
44
  lcd_string( Buffer_ms );
45
  set_cursor(0,1);
46
  lcd_string( Buffer_s );
47
}

und kann mir nicht erklären warum der zu langsam zählt.

Taktfrequenz ist 16MHz, fuses dafür sind gesetzt.
Eigentlich sollte es ja laut der Formel:
16 000 000  64  250 = 1000
in einer sekunde 1000 interrupts geben. und da 1sec = 1000ms sollte des 
j stimmen...

kann mir vll jemand helfen?

Mfg, Pat
OP #1506506
Lesenswert?

thx für die schnelle Hilfe, nun gehts habs noch n bissle mehr 
abgeändert.^^
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
#include <util/delay.h>
4
#include "lcd-routines.h"
5
#include <stdlib.h>
6

7
 
8
//Variablen für die Zeit
9
volatile unsigned int  millisekunden=0;
10
volatile unsigned int  sekunde=0;
11

12
int main(void)
13
{
14
  TCCR2 =(1<<WGM21) | (1<<CS20) | (1<<CS21);    //Prescaler 64 / OCR0 125: 8MHz:64:125 = 1KHz
15
  OCR2=250;
16
  TIMSK|=(1<<OCIE2);
17
  sei();                          //3)Interrupts aktivieren
18

19
   while(1)
20
   {
21
   }
22
 
23
   return 0;
24
}
25

26
void anzeigen (void)
27
{
28
    // ... umwandeln siehe FAQ Artikel bei www.mikrocontroller.net
29
  // WinAVR hat eine itoa()-Funktion, das erfordert obiges #include <stdlib.h>
30
  char Buffer_ms[20]; // in diesem {} lokal
31
  itoa( millisekunden, Buffer_ms, 10 ); 
32
  // ... ausgeben 
33
  char Buffer_s[20]; // in diesem {} lokal
34
  itoa( sekunde, Buffer_s, 10 ); 
35
  // ... ausgeben 
36
  lcd_init();
37
  set_cursor(7,1);
38
  lcd_string( Buffer_ms );
39
  set_cursor(0,1);
40
  lcd_string( Buffer_s );
41
}
42

43
ISR (TIMER2_COMP_vect)              //4)Führe diese ISR bei Overflow von TCNT0 aus
44
{
45
  millisekunden++;
46
  if (millisekunden == 1000)
47
  {
48
    sekunde ++;
49
    millisekunden = 0;
50
  }
51
  if(millisekunden % 100 == 0)
52
  {
53
  anzeigen();
54
  }
55
}
Moderator (Firma: Titel) Persönliche Seite #1506626
Lesenswert?

> nimm einen zweiten Timer
Wenn anzeigen() gerade ausgeführt wird, und länger als 1 ms dauert, dann 
hilft auch ein zweiter Timer nichts...

Richtigerweise wird lcd_init() genau 1 mal gemacht. Und dann in der 
Hauptschleife das anzeigen(). Für das Ausführen von anzeige() wird in 
der ISR ein Flag gesetzt.
Etwa so:
1
volatile char updateanzeige;
2
:
3
main () {
4
   while(1)
5
   {
6
     if (updateanzeige) {
7
        anzeigen();
8
        updateanzeige=0;  // fertig, Flag löschen
9
     }
10
   }
11

12
}
13
:
14
ISR (TIMER2_COMP_vect)              //4)Führe diese ISR bei Overflow von TCNT0 aus
15
{
16
  if (millisekunden == 1000)
17
  {
18
    sekunde ++;
19
    millisekunden = 0;
20
  }
21
  if(millisekunden % 100 == 0)
22
  {
23
    updateanzeige=1;  // Flag setzen
24
  }
25
}
#1507527
Lesenswert?

Patrick R. schrieb:

> edit: hab nu im datenblatt folgendes gefunden:
> The prescaled clock has a frequency of either f/8, f/64, f/256 or f/1024

Jede Wette, das Zitat stammt aus den Kapitel:
Timer/Counter0 and Timer/Counter1 Prescalers
(du verwendest Timer2)

Kann hier aber keiner wirklich kontrollieren, da wir ja immer noch nicht 
wissen, welcher AVR.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren