-         

Ergebnis 1 bis 2 von 2

Thema: Timer in C/ATmega8

  1. #1

    Timer in C/ATmega8

    Anzeige

    Hallo,
    ich möchte gerne einen Timer auf einem ATmega8 realisieren. Dieser soll von Programmstart aus hochzählen, z.B. in ms. Das hat den Vorteil, dass ich mir daraus beliebig viele Timer (natürlich nicht so genaue, nur für ungefähre Aufgaben, damit ich mit _delay_ms(); mein Programm nicht aufhalten muss) generieren lassen kann. Z.B. läuft mein Programm jetzt seit 100sek. Jetzt möchte ich z.B alle 10sek eine Sache machen, natürlich will ich den Rest meines Programms nicht aufhalten. Dann kann ich einfach sagen

    Code:
    zeitStart = momentaneZeit; //zeitStart=100
    while(true)
    {
      if((momentaneZeit-zeitStart)>10) //if(100-100>10), nach 10sek if(110-100>10), also nach 10sek
      {
        Aufgabe erledigen
    
        zeitStart=momentaneZeit;
      }
    
      Sonstige Aufgaben
    }
    Ich hoffe, ihr habt das Prinzip verstanden. Die Idee habe ich vom LEGO MINDSTORMS. Jetzt die theoretische Umsetzung:
    Ich habe einen 8MHz Quarz. Ich stelle meinen Vorteiler vom Timer 0 auf 1024 ein. 8000000/1024=7812,5, also 7,8125kHz, also 7,8125 Mal in der Sekunde wird das Interrupt (das oder der Interrupt?) ausgelöst. Der 8Bit Timer läuft also in 0,128sek durch und löst dann ein Interrupt aus. Wenn das Interrupt ausgelöst wird, muss ich also zu meiner Variable 0,128 dazu addieren. Jetzt habe ich einen Timer in 128ms Schritten.
    Ich habe aber auch noch den eigentlichen 8Bit Timer, der in diesen 128ms von 0-255 hoch zählt. Immer, wenn sich diese Zahl ändert (also von 0 auf 1, von 1 auf 2 [...], von 255 auf 0 usw.) können noch 0,128/256, also 0,0005, also 500us, dazu addiert werden. Ich habe also jetzt einen Endlostimer (natürlich nur bis zum Overflow der Variable) mit einer Auflösung von 500ms.
    Ist das soweit alles richtig gedacht, funktioniert das theoretisch?
    Jetzt die praktische Umsetzung:
    Hier nur mein Void zum Initialisieren, die Variable und das Interrupt. Den restlichen Code kann man sich dazu denken, mein Projekt ist sowieso etwas größer. Wenn mein restlicher Code zwingend notwendig ist, stelle ich ihn auch rein. Momentan habe ich das mit den halben ms noch nicht umgesetzt, erstmal Schritt für Schritt:
    Code:
    uint64_t tick;
    
    void init_TIMER()
    {
      TCCR0 =(1<<CS02) | (1<<CS00); //Vorteiler 1024
      TIMSK |= (1<<TOIE0);
    }
    
    ISR(TIMER0_OVF_vect)
    {
      tick+=0.128;
    }
    init_timer wird eben im int main vor der Endlosschleife aufgerufen, dann einfach die Abfragen, wie oben demonstriert.
    Welche Variable muss ich nehmen? Kann ich einfach die uint64_t nehmen, oder benötige ich ein float? Ist ja ein Dezimalbruch... WIe hoch kann mein Timer mit einem float zählen?
    Das Ganze funktioniert grundsätzlich, aber die Zeit haut nicht so ganz hin. Bevor ich da irgendwelche ausprobierten Zahlen auf tick aufaddiere, möchte ich wissen, wo der Rechenfehler ist, oder was noch zu beachten ist.
    Ich hoffe, ihr habt das Prinzip und das Problem verstanden.
    Vielen Dank für Eure Hilfe schonmal im Vorraus und
    Viele Grüße
    teamohnename

  2. #2
    Erfahrener Benutzer Robotik Visionär
    Registriert seit
    26.11.2005
    Ort
    bei Uelzen (Niedersachsen)
    Beiträge
    7.942
    Für dsa Hochzählen der Zeit sollte man eine Ganzzahl variable nehmen, also eher die Zeit in µs, vielfachen von 128 µs, oder einfach der Zahl der Überläufe (entspricht 256 mal 128 µs = 32,768 ms). Das sind dann rund 30 Interrupts pro Sekunde. Dafür reicht ggf, schon ein 16 Bit Word variable (bis ca. 2000 Sekunden) oder halt ein Long.

    Das hochzählen mit Fließkommazahlen geht im Prinzip ist aber recht langsam und man kann Rundungsfehler bekommen die sich irgendwann aufaddieren. Die Umrechnung in die Genaue Zeitskala kann man besser später beim Auslesen machen. Die FP Multiplikation ist auch nicht so langsam wird dann aber viel seltener gebraucht. Dabei kann man ggf. auch Abweichungen der Quarzfrequenz berücksichtigen.

    Der Fehler ist bei der Zeit für den Overflow, das sind rund 32 ms, nicht 128 ms. Außerdem sollte die Addition von Uint64 und Float ein Problem machen. Da müsste der Typ schon float sein.

Ähnliche Themen

  1. Timer auf ATMega8
    Von Lightstorm im Forum C - Programmierung (GCC u.a.)
    Antworten: 8
    Letzter Beitrag: 18.03.2010, 13:58
  2. Timer im Atmega8
    Von RomeoAdrian im Forum Assembler-Programmierung
    Antworten: 1
    Letzter Beitrag: 30.05.2007, 21:39
  3. timer von atmega8
    Von fed111 im Forum C - Programmierung (GCC u.a.)
    Antworten: 7
    Letzter Beitrag: 13.07.2005, 17:21
  4. ATmega8 und Timer
    Von seitenmaster im Forum C - Programmierung (GCC u.a.)
    Antworten: 1
    Letzter Beitrag: 01.06.2005, 14:39
  5. Timer vom ATMega8
    Von seitenmaster im Forum C - Programmierung (GCC u.a.)
    Antworten: 19
    Letzter Beitrag: 29.08.2004, 23:19

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •