Moin! Wir basteln im Moment zum ersten Mal ernsthaft mit nem ATmega8 und GCC herum und würden gerne um zu warten den Controller in den idle-mode setzen und ihn mit dem Overflow-interrupt von Timer0 wieder aufzuwecken. Wir haben soweit auch herausgefunden wie das geht, unser Controller geht in den Sleepmodus und wacht auch wieder auf; allerdings gibts beim Aufwachen einen kompletten Reset. Anhand der Beispiele aus dem Tutorial hatten wir das so verstanden, dass er nach dem sleep im Code da weitermacht wo er rein geschickt wurde. Unser (relevanter) Code sieht so aus: TCCR0 |= (1<<CS00)|(1<<CS02); // timer anmachen TIMSK |= (1<<TOIE0); // timer-overflow-interrupt anschalten set_sleep_mode(SLEEP_MODE_IDLE); // sleep fkt der sleep.h (natürlich included)... sleep_enable (); sei(); sleep_cpu(); // hier geht der AVR dann schlafen und wacht am Anfang des Programms wieder auf... ...weiterer Code Wir haben auch ausprobiert da noch ein Sleep disable reinzusetzen aber das hat am ganzen nichts geändert. Wenn uns jemand damit helfen könnte wäre das sehr nett, wir können irgenwie nichts zu diesem Problem finden. MfG Thomas
Habt ihr eine Interruptroutine für den Overflow? Nur ein "Dummy" der nicht wegoptimiert wird reicht. Es geht um die Sprungtabelle. xxx
Ömm nein haben wir nicht :) Wozu brauchen wir sowas denn und wie sieht sowas aus? Nachdem wir es wir es mit dem "TIMSK |= (1<<TOIE0);" geschafft hatten den Interrupt zu aktivieren waren wir davon ausgegangen, dass das ausreicht. Er erweckt den Controller ja auch wieder zum leben, nur an der falschen Stelle...
fractal schrieb: >Wozu brauchen wir sowas denn und wie sieht sowas aus? Da hättest du auch fragen können: Wozu braucht mann denn ein Datenblatt und wie sieht sowas aus? >Er erweckt den Controller ja auch wieder zum leben, nur an der falschen >Stelle... Klar, weil ihm ja niemand gesagt hat, wo er weitermachen soll. Dafür gibts nämlich die Sprungtabelle. Und wie die zu benutzen ist, steht im Datenblatt. Aber wozu braucht man sowas schon...
Jeder freigegebene Interrupt braucht einen Handler. Ansonsten schickt ihn der GCC zum BAD-ISR Handler, der default zum Resetvektor spring. Peter
> Nachdem wir es wir es mit dem "TIMSK |= (1<<TOIE0);" geschafft > hatten den Interrupt zu aktivieren waren wir davon ausgegangen, > dass das ausreicht. Damit sorgt man dafür, daß der Interrupt ausgelöst wird. Jetzt mußt du noch sagen, was dann gemacht werden soll. > Er erweckt den Controller ja auch wieder zum leben, nur an der > falschen Stelle... Die primäre Aufgabe eines Interrupts ist es, den Code des Interrupt-Handlers auszuführen. Das Aufwecken ist nur eine Zusatzfunktion.
@Klaus, peda, Rolf
müßt Ihr immer gleich alles verraten?
>Es geht um die Sprungtabelle.
Das hätte als Hinweis bis über das Wochenende reichen können.
Schade!
xxx
Erstmal vielen Dank für alle Antworten, super wie schnell das geht, auch wenn die Fragen doof sind. Warum sich manche allerdings die Zeit nehmen man solle im Datenblatt nachschauen verstehe ich nicht, wenn ihr meint ich sollte die Antwort selbst rausfinden postet halt nicht.. Im übrigen haben wir schon n Weilchen an dem Problem rumgeknabbert und sowohl im Datenblatt als auch im GCC Tutorial alles Mögliche gelesen, aber sind bisher nicht fündig geworden; das Datenblatt hat immerhin 300+ Seiten und das Tut immerhin 117. Da wir erstmal nur die Nebenfunktion des Interrupts brauchen habe ich mir um einen Handler keine Sorgen gemacht, der springende Punkt ist ja wohl das Default Verhalten, reset anstatt nichtstun :) Das jetzt im Datenblatt zu finden...nunja mit diesem Wissen sollte es ja einfach sein und auch nicht das ganze Wochenende dauern :)
Es sollte heißen "Warum sich manche allerdings die Zeit nehmen zu posten man solle im Datenblatt nachschauen" Jetz steht n "ISR(TIMER0_OVF_vect){}" im code und es funzt genau wie es soll. Anstatt ihm nicht zu sagen das er was machen soll sagen wir nun er soll nichts machen :)
Also es steht ganz vorne bei "Power Management and Sleep Modes"
1 | If an enabled interrupt occurs while the MCU is in a sleep mode, the MCU wakes up. The MCU is then halted for four cycles in addition to the start-up time, it executes the interrupt routine, and resumes execution |
2 | from the instruction following SLEEP. |
Wird gerne überlesen oder (noch schlimmer) der Compiler erkennt, daß die Interruptroutine leer ist und optimiert diese weg. Ist mir ja auch mal pasiert, woher sollte ich es sonst wissen ;D xxx
Den betreffeden Kram hab ich ja komplett gelesen. Nur eben auf die Idee dass er ohne Anweisung was er tun soll einfach n reset macht bin ich nicht gekommen.
> Nur eben auf die Idee dass er ohne Anweisung was er tun soll > einfach n reset macht bin ich nicht gekommen. Er hat immer eine Anweisung. Wenn der Interrupt an ist und ausgelöst wird, springt der AVR in den entsprechenden Eintrag in der Interrupt-Vektor-Tabelle und führt aus, was dort steht. Ob da was sinnvolles eingetragen ist, ist ihm Wurscht. Die avr-libc trägt da per Default für alle nicht explizit definierten Interrupts einen Neustart des Programms ein, weil ein ausgelöster Interrupt ohne dazugehörigen Handler ein Fehler im Programm ist. Anbieten würde sich das Lesen der avr-libc-Doku über Interrupts, insbesondere der Absatz "Empty interrupt service routines".
fractal schrieb: >Warum sich manche allerdings die Zeit nehmen >man solle im Datenblatt nachschauen verstehe ich nicht Dann hast du ein grundlegendes Problem. Im Datenblatt stehen alle notwendigen Informationen, nur muss man halt auch bereit sein, etwas Zeit in die Lektüre zu investieren. >das Datenblatt hat immerhin 300+ Seiten Ja und? Es gibt doch ein Inhaltsverzeichnis.
Da fehlt ein Wort, habe ich im Post später korrigiert. Ich weiß wohl dass die Antwort irgendwo da ist. Im Datenblatt, im Tutorial, im Wiki, auf anderen Seiten wie RN, avrfreaks etc. oder wie in diesem Fall wohl am ehesten in den manpages der avr-libc. Das Problem ist halt, dass ich das Problem Mangels Erfahrung nicht einordnen kann und auch nicht weiß wo ich am besten suchen soll. Und da es hier ja offensichtlich genug Leute gibt die gerne bereit sind meine Frage zu beantworten oder zumindest Hinweise in die richtige Richtung geben gehe ich dann hin und Frage. Wenn du meinst dass ich es mir damit zu einfach mache - okay, dann antworte nicht. Ich kann nur nicht verstehen dass du dir dann die Zeit nimmst einen wenig hilfreichen Kommentar abzugeben.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.