mikrocontroller.net

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


Autor: Snooze (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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:
#include <avr/io.h>
#include <avr/interrupt.h>

//Variablen für die Zeit
volatile unsigned int  zehnmicrosekunden=0;
volatile unsigned int  millisekunden=0;
volatile unsigned int  sekunde=0;
volatile unsigned int  minute=0;
volatile unsigned int  stunde=0;
 
int main (void) {            

  //Register configurieren
  DDRC = 0xff;             
  PORTC = 0xff;
  
  //Timer 0 konfigurieren
  TCCR0A =(1<<WGM01);
  TCCR0B = (1<<CS00); //Prescaler = 1 
  OCR0A = 200;

  //Compare Interrupt aktivieren
  TIMSK0|=(1<<OCIE0A);

  //Globale Interrupts aktivieren
  sei();
   
  while(1) {
      PORTC = ~sekunde;
   }//Ende der while(1) schleife
  return 0;                 
}

// Der Compare Interrupt Handler
ISR (TIMER0_COMPA_vect){

  zehnmicrosekunden++;

  if(zehnmicrosekunden==100){
    millisekunden++;
    zehnmicrosekunden=0;  
  }
  if(millisekunden==1000){
    sekunde++;
    millisekunden=0;
  }
  if(sekunde==60){
    minute++;
    sekunde=0;
  }
  if(minute==60){
    stunde++;
    minute=0;
  }
}

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

Gruß Manuel

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

CKDIV8-Fuse gesetzt?

MfG Spess

Autor: Snooze (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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 ?

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

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

Ja.

MfG Spess

Autor: Snooze (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke für die Antwort, dann mich das mal raus.

Autor: Michael H. (morph1)
Datum:

Bewertung
0 lesenswert
nicht 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)

Autor: Snooze (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: THoff (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Michael H. (morph1)
Datum:

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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
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.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.