mikrocontroller.net

Forum: Compiler & IDEs POWER DOWN MODUS


Autor: toni (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
HALLO.

Momentan hänge ich in meinem Projekt.

Folgendes Problem: Wie schon öffters in diesen Forum angesprochenes 
Problem, der Power Down Modus.

Aus Energiegründen muß sich mein 8518 schlafen legen,bis
ein externer Interrupt(an INT1) in wieder aufweckt.
Das Schalfenlegen mit folegenden Source Code:

void sleep(void)
{
  sbi(SREG,7);
  sbi(GIMSK,7);

  sbi(MCUCR,4);
  sbi(MCUCR,5);


  lcd_puts_P( "SLEEP" );
  asm volatile("sleep");
}

ist kein Problem.
Aber das Aufwachen,bzw das was er nach dem Aufwachen anstellt.

Ich habe zwar das Datenblatt gelesen, aber hab noch immer keine Antwort 
darauf ob meine Register im Power Down Modus aufrecht erhalten 
werden.Ich Programmier in C unter AVR Studio 3.56.
Lange Rede kurzer Sinn.Gibt es eine Möglichkeit die Register
aufrecht zu Halten.Auser extern
Weiters würde es mich interresieren,wie ich richtig aus den Power Down 
Modus aufwache.Falls ich richtig liege,fängt das Programm im main an 
nach einem Power Down Modus.

Ich habe schon öffters in diesem Forum diese Problemstellung
gelesen, aber keiner hat noch eine Lösung in C ,bzw einen
Erklärung abgegeben.

Ich habe zwar in Assembler Interrupts programmiert, aber in C ist es 
meine erste Interrupt .

Ich hoffe es gibt da drausen jemand, der mir weiter helfen kann.

Danke Toni.

Autor: Jörg Wunsch (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Selbstverständlich bleiben im sleep-Modus alle Registerinhalte
erhalten.  Weitergearbeitet wird dort, wo er sich schlafen
gelegt hat.  Hat mit C oder Assembler oder Interrupt auch nicht
viel zu tun abgesehen davon, daß Du ihn mittels Interrupt
aufweckst, aber die Interruptbehandlung selbst darf dabei durch
eine leere Routine erfolgen, wenn Dich der Interrupt sonst nicht
interessiert.

Ach ja, lies das Datenblatt mal durch.  Mir ist so, als würde
erst noch ein CPU-Befehl nach dem sleep abgearbeitet, bevor er
in die Interruptroutine springt.

Autor: toni (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo.

Das mein Register erhalten bleibt ist mir jetzt klar.
Steht ja auch Slepp Modes und nicht Mode.

Aber wo springe ich in C hin nach einem Interrupt.
In Asembler ist mir klar Adresse 0x02,aber wohin in C?:

Autor: Jörg Wunsch (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nein, Du hast das leider immer noch nicht verstanden.  Weder in
Assembler noch in C ,,springt'' das Programm irgendwo hin.  Es
wird dort fortgesetzt, wo Du es zuvor schlafen gelegt hast.  In
Deinem obigen Beispiel beendet es damit also die Funktion sleep()
und kehrt zu deren Aufrufer zurück.  Dort solltest Du dann wohl
eine Schleife drumrum haben...

Autor: toni (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Falls ich mich nicht irre, gibt es eine Interrupt Routine,
Bei einem Interrupt,egal ob intern oder extern, "springt" das Programm 
in eine Interruptroutine, danach kehrt das Programm wieder an die Stelle 
(plus eins)zurück, wo meine Interrupt aufgerufen worden ist.Das ist doch 
richtig oder ?.
Aber wo komme ich in C hin ?.

Autor: Jörg Wunsch (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja, das ist richtig.  Das ist in C nicht anders als in Assembler,
Du kommst dort wieder raus, wo das Programm unterbruchen worden
ist.

Wo das genau ist, kann man normalerweise nicht sagen.  Im Falle
des Aufwachens aus dem sleep kann man es ein wenig sagen, wie
ich schon schrob: Du machst den sleep, dann kommt der Interrupt,
dann wird meiner Erinnerung nach (-> Datenblatt) noch ein
CPU-Befehl abgearbeitet, bevor dann die Interruptroutine gerufen
wird.  Danach geht's normal weiter, wo das Programm vorher
unterbrochen worden ist.

Welches Stück Deines C-Programms der eine CPU-Befehl ist, der
nach dem sleep vor der Interruptroutine noch abgarbeitet wird,
kannst Du ohne Ansehen des generierten Assemblercodes nicht sagen.
Wenn das für Dich wirklich bedeutungsvoll ist, daß noch nichts
aus der Hauptschleife abgearbeitet wird, mußt Du explizit noch
einen NOP dahintersetzen.

Autor: toni (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe jetzt eine Lösung:


SIGNAL (SIG_INTERRUPT1)
{


cli();
cbi(SREG,7);
return(0);

}

Wenn ich diese Funktion einfüge funktionierts.

mfG TONI

Autor: Joerg Wunsch (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Huh?

Du hast

asm volatile("nop");

sehr aufwendig niedergeschrieben!  Denk doch wenigstens mal
hinterher drüber nach, wenn Du schon nur mit trial&error
herumhackst (sorry).

Innerhalb SIGNAL() sind Interrupts ausgeschaltet.  sbi(SREG,7)
ist, von der obsoleten Syntax mal abgesehen, von der Wirkung
identisch zu cli().  Da das I-Flag aber sowieso ausgeschaltet
ist, sind beides effektiv NOPs.

Das return 0; sollte eine Compilerwarnung verursachen (und
ansonsten ignoriert werden), da SIGNAL() keinen Wert zurückgibt
(wohin sollte es den auch zurückgeben?).

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.