Ok. Ich weiss ich bin jetzt besoffen und das ist auch gut so, darum mag man mir die Tippfehler verzeihen. Ich bastle seit Wochen an meinem Board rum um den CAN128 in den Schlaf zu versetzen, was mich inzwischen 3 oder mehr Wochenenden gekostet hat. Das Ziel: Die CPU soll schlafen und sich aus einer kleinen Knopfzelle nähren wenn an PINE,PE7 ein Lowlevel anliegt und soll aus dem Schlaf zurückkehren, wenn PINE,PE7 wieder Spannung hat (High - Level), Natürlich soll dan noch immer die Uhrzeit stimmen. Es ist ein 32?Xde irgendwas am Port und das ASSR Register ist entsprechend eingestellt. // Oszillatoren einstellen setbit(ASSR,AS2); // 2. Oszillator für TOSC aktivieren // Clocktimer aktivieren TCCR2A = 0x05; // Prescaler Timer 2 = 128, extern 32kHz Clock setbit(TIMSK2,OCIE2A); // Interrupt enable Timer 2 while(checkbit(ASSR,TCN2UB) || checkbit(ASSR,OCR2UB) || checkbit(ASSR,TCR2UB)) asm("NOP"); und ausgewertet wird auch ganz artig SIGNAL(SIG_OUTPUT_COMPARE2) { setbit(GPIOR2,GPIOR01); // Sekundenbit } wird gesetzt und die Uhrroutine arbeitet es ab, wenn Zeit dafür ist. Ich habe zig Anleitungen und natürlich das vermaledeite Handbuch des CAN 128 gelesen, den Befehl asm(sleep) habe ich natürlich nirgendwo gefunden sondern bin in dem Programmbeispiel des Butterfly darüber gestolpert. Da der Stromverbrauch im Sleep-Modus noch immer bei 10 - 12 mA lag hatte ich schon die Hardware in Verdacht... Heute dann die Ernüchterung. Bei einem Codeschnipsel, der etwa diesem hier clearbit(EIMSK,INT7); cli(); SMCR = 0x0c; sleep_enable(); sei(); sleep_cpu(); while(!checkbit(PINE,PE7)) {totzeitx++; asm volatile ("sleep");} sleep_disable(); sei(); ähnlich gewesen sein könnte war totzeitx nach 3 Sekunden bei einer 5stelligen Zahl. Es sollte dieses räudige 64beinige Mistvieh doch schlafen?! und nur jede Sekunde erwachen, wenn SIGNAL(SIG_OUTPUT_COMPARE2) klingelt. Wie kann es sich da in 3 Sekunden auf 27?x? hochschrauben? Ergo. Die Sau schläft nicht. Ich bin mir nicht sicher ob ich überhaupt noch wissen will, warum das elende Mistvieh nicht schläft, aber vieleicht hat jemand eine Routine für mich wie ich den Hund zum schlafen bringe. Prosit!
ceberus wrote: > Ergo. Die Sau schläft nicht. Ja, der Powerdown Mode ist ziemlich tückisch. Man muß eine bestimmte Abfolge einhalten und besonders auf die Interrupts achten. Die WINAVR-Funktionen tragen auch das ihre zur Verwirrung bei, da sie nicht interruptfest sind. Da steht zwar im "sleep.h" schön versteckt wichtiger Text, aber wer liest das schon so gründlich. Am besten fährt man, wenn man sie daher nicht benutzt und alles selber macht. Hier mal ein funktionierendes Beispiel auf nem ATtiny45: http://www.mikrocontroller.net/attachment/33635/SLEEP.C Peter
Ach Peter, es ist ja nicht so, dass ich Deine Hilfen und Erklärungen nicht zu schätzen wüsste, auch wenn ich mir dabie immer vorkomme wie Alice im Wunderland. Das Beispiel sieht ja auch schick aus, aber ??? Wie und wann kommt Dein Tiny aus der For-Schleife am Ende wieder raus? Und wo lässt man die Uhr? Und wo ist jetzt eigentlich der elementare Fehler in meinem Geschriebsel? Macht es einen Unterscheid, ob ich das Register so SMCR = 0x0c; oder MCUCR = 1<<SE^1<<SM1; beschreibe? wenn die 0 gesetzten Bits ohnehin nicht belegt sind?
ceberus wrote: > Wie und wann kommt Dein Tiny aus der For-Schleife am Ende wieder raus? Garnicht, das ist die Mainloop, da kommt nie ein MC raus. Sie ist hier leer (außer dem Sleep), aber das ist ja nur ein Grundgerüst. > Und wo lässt man die Uhr? Im T2-Interrupt oder in der Mainloop. Ganz wo Du willst. > Und wo ist jetzt eigentlich der elementare Fehler in meinem > Geschriebsel? Daß es nur zusammenhanglose Codefetzen sind. > Macht es einen Unterscheid, ob ich das Register so SMCR = > 0x0c; oder MCUCR = 1<<SE^1<<SM1; beschreibe? Ja, das letzte ist lesbarer. Das Beispiel soll zeigen, daß es am sinnvollsten ist, die entsprechenden Sleepmodi in nem Interrupt zu setzen. Dann muß das Main nur noch das eigentliche Sleep machen, wenn es alle Tasks fertig hat. Wichtig ist, nur das nackte SLEEP, nicht das sleep_mode !!! Es ergibt IMHO keinerlei Sinn, das Sleepenable separat von den Sleepmodis zu setzen. Entweder man will schlafen oder nicht. Damit gibt es keine Konflikte mehr. Peter
Nun ja, ich hatte mir die Sache aus dem sleep.h zusammengeklaubt. Geholfen hat es nix. Warum das Sleep_enable immer separat gesetzt wurde, kann ich auch nicht sagen, ich habe es überall so gefunden und weil es bei mir nicht wirklich funktionierte, wenn ich es gleich mit geschrieben habe, habe ich es eben mal so herum probiert. Sleep im Interrupt, sleep ohne interrupt, sleep in der Endlosschleife, ... langsam gehen mir die Ideen aus... Vermutlich muss ich es noch einmal ganz von Vorne anfangen und die komplette Software um das Sleep-Modul herumschreiben ...
cerberus wrote: > Vermutlich muss ich es noch einmal ganz von Vorne anfangen > und die komplette Software um das Sleep-Modul herumschreiben ... Eigentlich nicht. Man sollte erst die Funktionalität fertig stellen und das Sleep ganz zum Schluß dazubasteln. Dazu braucht es nur eine Stelle im Main, wo man denkt, grad nichts mehr zu tun zu haben und dann das Sleep dahin setzen. Das Sleep Mode einstellen machen dann die Interrupts oder das Main unter Interruptsperre. Die Mainloop darf natürlich keine Delayschleifen enthalten, das würde ja einem Sleep zuwider laufen. Also immer schön in Sleep gehen und Timerinterrupts aufsetzen für die Delays. Peter
Ich komme aus der SPS-Programmierung ;-) bei mir gibt es keine delays ;-), wird alles über Merker gesteuert. Das sleep in der Main-schleife und die Initialisierung in der ISR hatte ich gestern auch schon, hat aber auch nicht geholfen ... Ich muss noch mal schauen, was passiert, wenn ich vorher alle Interrupts kille, bevor ich den Kollegen schlafen lege. Irgend wo da war ich gestern nicht mehr aufnahmefähig ... Ich weiss, dass er dann nicht mehr aufwacht, gerade das will ich ja wissen, oder ob er dann einfach sang-und Klanglos weitermacht. Was denkst zu zu einem Main in der Form int main( void ) { // Initialisierung und vorgeplänkel while(1) { if(!checkbit(PINE,PE7)) { totzeitx++; asm volatile ("sleep"); } else { // Hauptprogramm } }
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.