- LiFePO4 Speicher Test         
Ergebnis 1 bis 9 von 9

Thema: ATMEGA8 Timer etwas zu schnell

  1. #1
    Neuer Benutzer Öfters hier
    Registriert seit
    22.12.2019
    Beiträge
    19

    ATMEGA8 Timer etwas zu schnell

    Anzeige

    LiFePo4 Akku selber bauen - Video
    Hallo,

    ich habe folgenden Teil von einem ATMEGA32-16 auf den ATMEGA8 übernommen.

    Nur leider läuft der Timer nicht bei 8 Sekunden über sondern bei 2 wenn ich mit dem Handy richtig stoppe.

    Vielleicht könnt Ihr mir dazu auch einen Tipp geben. Am ATMEGA hängt ein 32,768kHz Crystal an TOSC1/TOSC2

    Und so sieht mein bereits reduzierter und getesteter Quellcode aus
    Code:
    //-U lfuse:w:0xe2:m -U hfuse:w:0xd9:m
    
    #define MCU   atmega8
    #define F_CPU 2000000UL
    
    #include <avr/io.h>
    #include <util/delay.h>
    #include <avr/interrupt.h>
    #include <avr/sleep.h>
    #include <avr/power.h>
    
    
    #define BT_EN_REGISTER DDRC
    #define BT_EN_PORT     PORTC
    #define BT_EN_PIN      PC0
    
    #define LED_REGISTER   DDRC
    #define LED_PORT       PORTC
    #define LED_RED_PIN    PC5
    #define LED_GREEN_PIN  PC4
    #define LED_BLUE_PIN   PC3
    
    
    // Timer2 Interrupt (Occurs every 8 Seconds)
    ISR(TIMER2_OVF_vect) {
       LED_PORT ^= (1 << LED_RED_PIN);
    }
    
    
    int main(void){
       // Direction Registers
       DDRB = 0x00;            // B as input
       DDRC = 0x00;            // D as Input
       DDRD = 0x00;            // D as Input
       
       // Set Output Registers
       LED_REGISTER   |= (1 << LED_RED_PIN);      // LED as output
       LED_REGISTER   |= (1 << LED_GREEN_PIN);    // LED as output
       LED_REGISTER   |= (1 << LED_BLUE_PIN);     // LED as output
    
       // Ports to LOW (GND no Pullup)
       PORTB = 0x00;
       PORTC = 0x00;
       PORTD = 0x00;
          
          // Configure Timer2 (Countdown Timer)
          ASSR  = (1<< AS2);                                 // Timer2 asynchron takten
          _delay_ms(2000);                                   // Einschwingzeit des 32kHz Quarzes
          //TCCR2  = 6;                                      // Vorteiler 256 -> 2s Überlaufperiode
          TCCR2 |= (1 << CS22) | (1 << CS21) | (1 << CS20);  // Prescaler 1024 -> 8s Überlaufperiode
          while((ASSR & (1<< TCR2UB)));                      // Warte auf das Ende des Zugriffs
          TIFR   = (1<<TOV2);                                // Interrupts löschen (*)
          TIMSK |= (1<<TOIE2);                               // Timer overflow Interrupt freischalten
    
    
          // Release Interrupts
          sei();
          
          while (1){        
             LED_PORT &= ~(1<<LED_GREEN_PIN);
             LED_PORT |= (1<<LED_BLUE_PIN);
             // WICHTIG!
             // Wenn der Timer2 im asynchronen Modus periodisch zum Wecken aus dem Sleep Mode
             // genutzt wird, dann muss vor dem Wiedereintritt mindestens
             // 1 Oszillatortakt des Timers abgewartet werden (~30us), um die Interruptlogik 
             // wieder zu aktivieren, anderenfalls wacht der AVR nicht mehr auf.
             // Die folgenden zwei Zeilen tun dies.
             // Nur wenn sichergestellt ist, dass der Interrupt + Hauptschleife länger als 30µs dauern,
             // kann man den Test weglassen
             OCR2 = 0;                       			// Dummyzugriff
             while((ASSR & (1<< OCR2UB)));   			// Warte auf das Ende des Zugriffs
          
             // Go to sleep
             set_sleep_mode(SLEEP_MODE_PWR_SAVE);
             sleep_mode();                   			// in den Schlafmodus wechseln
          
             // hier wachen wir wieder auf
             
             LED_PORT &= ~(1<<LED_BLUE_PIN);
             LED_PORT |= (1<<LED_GREEN_PIN);
          }
       
    }
    Aktuelles Verhalten. Programm startet und geht in den Tiefschlaf. (Blaue LED an)
    Dann fängt die Rote LED im an zu blinken. 2 Sekunden an, 2 Sekunden aus.
    Erwartet hätte ich über den Vorteiler den ich mal berechnet habe 8 Sekunden.

  2. #2
    Erfahrener Benutzer Robotik Einstein Avatar von Searcher
    Registriert seit
    07.06.2009
    Ort
    NRW
    Beiträge
    1.702
    Blog-Einträge
    133
    Zitat Zitat von Tux12Fun Beitrag anzeigen
    Code:
          _delay_ms(2000);                                   // Einschwingzeit des 32kHz Quarzes
          //TCCR2  = 6;                                      // Vorteiler 256 -> 2s Überlaufperiode
          TCCR2 |= (1 << CS22) | (1 << CS21) | (1 << CS20);  // Prescaler 1024 -> 8s Überlaufperiode
    Erwartet hätte ich über den Vorteiler den ich mal berechnet habe 8 Sekunden.
    Würde ich auch erwarten.
    Wechselt die Blinkfrequenz der roten LED mit Vergrößern des _delay_ms Wertes?
    TCCR2 würde ich nicht verodern sondern den Prescale Wert direkt zuweisen.

    Gruß
    Searcher
    Hoffentlich liegt das Ziel auch am Weg
    ..................................................................Der Weg zu einigen meiner Konstruktionen

  3. #3
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    07.03.2011
    Beiträge
    1.899
    Zitat Zitat von Tux12Fun Beitrag anzeigen
    Nur leider läuft der Timer nicht bei 8 Sekunden über sondern bei 2 wenn ich mit dem Handy richtig stoppe.
    Die Überschrift führt da massiv in die Irre. Ein Faktor 4 ist nicht "etwas". Die Ursache ist da natürlich eine andere. Für "etwas" müsste man nach den Kondensatoren am Quarz oder an ähnlicher Stelle in der Hardware schauen, bei einem Faktor 4, einer Potenz von 2, ist es mit 99,9% Software. Da ist Datenblatt lesen angesagt.

    MfG Klebwax
    Strom fließt auch durch krumme Drähte !

  4. #4
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    05.11.2007
    Beiträge
    1.076
    Hallo Tux12Fun,

    ich hab mit Atmels noch nichts gemacht, aber eine Idee hätte ich evtl.
    Bist Du Dir sicher, dass der Controller auch wirklich mit dem externen Quarz läuft ?
    Lässt sich einfach feststellen: Ein Bein vom Quarz ablöten, wenn er dann immer noch läuft, stimmt mit der Konfiguration was nicht,
    dann läuft er mit dem internen RC-Oszillator.
    Man muss bei den Atmels wohl einige Einstellungen mit den FUSES machen,
    diese Zeile scheint in deinem Code (1. Zeile) auskommentiert zu sein.

    Siro

  5. #5
    Erfahrener Benutzer Robotik Visionär Avatar von oberallgeier
    Registriert seit
    01.09.2007
    Ort
    Oberallgäu
    Beiträge
    8.651
    Zitat Zitat von Siro Beitrag anzeigen
    .. eine Idee hätte ich evtl .. muss bei den Atmels wohl einige Einstellungen mit den FUSES .. scheint in deinem Code (1. Zeile) auskommentiert zu sein ..
    Darüber wunderte ich mich auch schon ne Weile. Die Einstellung ergibt-ergäbe

    Int. RC Osc. 2 MHz; Start-up time: 6 CK + 64 ms

    Zumindest stimmt damit der im Code genannte Takt von 2 MHz. WENN der Controller die auskommentierte Einstellung auch wirklich intus hat. Weiter bemerkenswert ist dabei aber der Unterschied zwischen dem auskommentierten
    //TCCR2 = 6; // Vorteiler 256 -> 2s Überlaufperiode
    und dem
    TCCR2 |= (1 << CS22) | (1 << CS21) | (1 << CS20); // Prescaler 1024 -> 8s Überlaufperiode

    das ist genau der Faktor vier - von dem hier die Rede ist.

    Wie Klebwax schreibt : ".. bei einem Faktor 4, einer Potenz von 2, ist es mit 99,9% Software ..".

    Oder meine (früher oft benutzte) Plattitüde : ".. Controller programmieren ohne Datenblatt ist eines der letzten Abenteuer unserer Tage ..". Wobei ich sicher bin, dass hier das Datenblatt gelesen wurde - nur die Fuses zu setzen/lesen ist manchmal "abenteuerlich" *gg*

    @Tux12Fun : Viel Erfolg.
    Ciao sagt der JoeamBerg

  6. #6
    Neuer Benutzer Öfters hier
    Registriert seit
    22.12.2019
    Beiträge
    19
    Hallo,

    tut mir leid, dass ich erst jetzt zum antworten kann.

    Der Microcontroller läuft tatsächlich mit 2Mhz und die kommentierte Zeile mit den Fuses ist gesetzt.
    Diese habe ich mit avrdude geschrieben und mir dort einfach notiert, damit ich die Einstellungen im parat habe.

    Der Vorteiler mit 6 war aus einem Beispiel das ich damals abgekupfert habe und ist auch wirklich Kommentar.
    Gesetzt ist Prescaler 1024 ich werde als nächstes mal den Versuch mit dem verdoppeln des delays machen.

    Der Quarz ist auch tatsächlich aktiv. Ziehe ich den Quarz aus dem Steckbrett bleibt die LED stehen.
    Wenn ich das alles richtig verstanden habe wechselt der Controller beim sleep Mode auf den externen Quarz

    Ich habe auch fleißig im Datenblatt gesucht. Ob ich noch etwas falsch mache, da der Code auf dem ATMEGA32 läuft
    und auf dem ATMEGA8 eben nicht.

    Ja die Abweichung zwischen 2 Sekunden und 8 ist enorm und ich hätte gerne wieder 8 Sekunden

    - - - Aktualisiert - - -

    Ich habe nun mal den delay_ms erhöht allerdings hat das keine Auswirkung. Dann habe ich den Prescaler auf 6 gesetzt LED blinkt ca jede Sekunde.

    Dann auf 7 das müsste wenn ich richtig gerechnet habe CS22 CS21 CS20 sein also 8 Sek. Aber die LED blinkt wie zuvor alle 2 Sekunden.

    Quarz ziehen führt zum sofortigen Stop

    - - - Aktualisiert - - -

    Rätsel gelöst und ihr habt mit Hardware recht. Kaum fügt man 2x 27pf und Masse hinzu läuft es korrekt. Beim Atmega32 brauchte ich die nicht 🙈

  7. #7
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    02.08.2006
    Ort
    Würzburg, Germany
    Beiträge
    716
    Hallo,

    kannst du mal mit einer simplen Delay-Schleife ohne Interrupts prüfen, ob der Controller wirklich auf 2 MHz läuft?

    Viele Grüße
    Andreas

  8. #8
    Neuer Benutzer Öfters hier
    Registriert seit
    22.12.2019
    Beiträge
    19
    Hallo Bumbum,
    Ja das tut er bis er in den sleep mode geht

  9. #9
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    02.08.2006
    Ort
    Würzburg, Germany
    Beiträge
    716
    Hallo Tux12Fun,

    ich bin mir jetzt nicht sicher ob ich dein Programm richtig verstanden habe. Im Overflow-Interrupt wird die rote LED eingeschaltet und nach dem Sleep wieder aus?

    Könnte es sein, dass der Controller noch von etwas anderem wieder aufgeweckt wird? Das sollte über das Verhältnis An- und Auszeit der LED herauszufinden sein? Falls ja solltest du im Datenblatt mal die Wake-Sourcen prüfen. Wenn dies nicht möglich ist wäre eine weitere Lösung dann ein Flag im Overflow-IRQ "getoggelt". Die LED steuerst du dann nach dem Sleep über dieses Flag.

    Ich würde dafür auch mal das Rücksetzen des Timers in der Hauptschleife rausnehmen. Vielleicht pfuscht dass dazwischen? Der Timer sollte sich nach einem Overflow automatisch zurücksetzen. Wenn du da zwischendurch den Timer änderst kann dein Takt nicht mehr passen.

    Viele Grüße
    Andreas
    Viele Grüße
    Andreas

Ähnliche Themen

  1. [ERLEDIGT] 16bit Timer Atmega2560 läuft zu schnell
    Von QuadV im Forum C - Programmierung (GCC u.a.)
    Antworten: 6
    Letzter Beitrag: 19.12.2013, 08:49
  2. Timer auf ATMega8
    Von Lightstorm im Forum C - Programmierung (GCC u.a.)
    Antworten: 8
    Letzter Beitrag: 18.03.2010, 13:58
  3. Nach ca 15 Minuten etwas auslösen, ohne Timer zu benutzen?
    Von x8r im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 3
    Letzter Beitrag: 21.03.2007, 17:36
  4. timer von atmega8
    Von fed111 im Forum C - Programmierung (GCC u.a.)
    Antworten: 7
    Letzter Beitrag: 13.07.2005, 17:21
  5. ATmega8 und Timer
    Von seitenmaster im Forum C - Programmierung (GCC u.a.)
    Antworten: 1
    Letzter Beitrag: 01.06.2005, 14:39

Berechtigungen

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

LiTime Speicher und Akkus