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
Ö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...
> 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 :)
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.