Forum: Mikrocontroller und Digitale Elektronik Timer: statt 1s Takt hab ich einen 8-10s Takt


von Snooze (Gast)


Lesenswert?

Hallo ich versuch einen Timer zu bauen mit dem ich die Zeit messen kann, 
leider ist die Taktzeit völlig anders als erwartet.

Hardware:
- Atmega 88
- 20MHz Oszillator

Meine Idee war, einen Timer mit 20MHz zählen zu lassen der nach 200 
Takten zurückgesetzt wird. Im entsprechenden Interupt zähle ich diese 
bis 100. Also alle 100 Interupts habe ich dann eine Millisekunde * 1000 
= Sekunden.
Leider funktioniert es nicht ganz.

Systemtakt: 50ns
Interrupttakt : 50ns * 200 = 10µs
Millisekundentakt : 10µs * 100 = 1ms
Sekundentakt : 1ms * 1000 = 1s

Mein code:
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
4
//Variablen für die Zeit
5
volatile unsigned int  zehnmicrosekunden=0;
6
volatile unsigned int  millisekunden=0;
7
volatile unsigned int  sekunde=0;
8
volatile unsigned int  minute=0;
9
volatile unsigned int  stunde=0;
10
 
11
int main (void) {            
12
13
  //Register configurieren
14
  DDRC = 0xff;             
15
  PORTC = 0xff;
16
  
17
  //Timer 0 konfigurieren
18
  TCCR0A =(1<<WGM01);
19
  TCCR0B = (1<<CS00); //Prescaler = 1 
20
  OCR0A = 200;
21
22
  //Compare Interrupt aktivieren
23
  TIMSK0|=(1<<OCIE0A);
24
25
  //Globale Interrupts aktivieren
26
  sei();
27
   
28
  while(1) {
29
      PORTC = ~sekunde;
30
   }//Ende der while(1) schleife
31
  return 0;                 
32
}
33
34
// Der Compare Interrupt Handler
35
ISR (TIMER0_COMPA_vect){
36
37
  zehnmicrosekunden++;
38
39
  if(zehnmicrosekunden==100){
40
    millisekunden++;
41
    zehnmicrosekunden=0;  
42
  }
43
  if(millisekunden==1000){
44
    sekunde++;
45
    millisekunden=0;
46
  }
47
  if(sekunde==60){
48
    minute++;
49
    sekunde=0;
50
  }
51
  if(minute==60){
52
    stunde++;
53
    minute=0;
54
  }
55
}

Noch als Info: Den Systemtakt hab ich auf extern gestellt. Sonst ist 
alles so gut es ging, dem Tutorial nachempfunden.

Gruß Manuel

von spess53 (Gast)


Lesenswert?

Hi

CKDIV8-Fuse gesetzt?

MfG Spess

von Snooze (Gast)


Lesenswert?

Hmm ja, also zumindest zeigt mir AVRStudio dort ein Häcken an. Das 
müsste wohl gesetzt heißen und somit kann ich mir mein Fehler wohl 
erklären...


CKDIV8 heißt dann wohl das ich statt 20MHz nur 2.5MHz habe, oder ?


Was ist da besser ?

von spess53 (Gast)


Lesenswert?

Hi

>CKDIV8 heißt dann wohl das ich statt 20MHz nur 2.5MHz habe, oder ?

Ja.

MfG Spess

von Snooze (Gast)


Lesenswert?

Danke für die Antwort, dann mich das mal raus.

von Michael H. (morph1)


Lesenswert?

aja und die teilung finde ich etwas niedrig, das abarbeiten eines 
interrupt dauert ja auch ne weile, eventuell zählst du doch besser mehr 
takte oder benutzt vorteiler (falls der atmel das kann)

von Snooze (Gast)


Lesenswert?

Also durch das Abschalten von CKDIV8 läuft es jetzt perfekt.

Das mit dem prescaler muss ich mir noch überlegen, es soll später eine 
recht zeitkritische Anwendungen werden und ich brauche da vielleicht 
einen Takt im µs Bereich.

von THoff (Gast)


Lesenswert?

Solange das Clear Timer on Compare (CTC) Register gesetzt ist sehe ich 
nicht wie die Ausführungszeit des Interruts relevant ist?
Okay da ist :
 TCCR0A =(1<<WGM01);
nicht besonders glücklich diese Namensänderung aber funktioniert

von Michael H. (morph1)


Lesenswert?

ich meine auch nicht gerade das er ungenau zählen wird, aber man 
verschwendet unnötig rechenzeit.

von Karl H. (kbuchegg)


Lesenswert?

Ziemlich viel Rechenzeit geht durch ungeschickte Wahl der Datentypen 
verloren.
zehnmicrosekunden muss nur bis 100 zählen. Trotzdem brauchst du für 
einen unsigned int die 16 Bit Arithmetik zum Hochzählen und Vergleichen. 
Wenn du das als unsigned char machst, fällt die Hälfte Code dafür schon 
mal weg. Selbiges für Sekunden, Minuten und Stunden. Alleine durch den 
Datentypwechsel kann man die ISR schon um einiges 'leichter' machen.

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.