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
Aktuelles Verhalten. Programm startet und geht in den Tiefschlaf. (Blaue LED an)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); } }
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.
Hoffentlich liegt das Ziel auch am Weg
..................................................................Der Weg zu einigen meiner Konstruktionen
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 !
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
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
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 🙈
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
Hallo Bumbum,
Ja das tut er bis er in den sleep mode geht
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
Lesezeichen