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

Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt. Bitte hier nur auf die ursprüngliche Frage antworten, für neue Fragen einen neuen Beitrag erstellen.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.