sleep_cpu() von #include <avr/sleep.h>

Janiiix3

Aktives Mitglied
28. Sep. 2013
1.333
10
38
Hannover
Sprachen
  1. ANSI C
  2. C#
Hallöchen.

Ich versuche gerade bei nem XMEGA den Sleep Mode zu aktivieren.
Das klappt leider nicht ganz ohne Hilfe der oben genannten Funktion.

...


CodeBox C
extern void sleep_cpu (void);
#else
#define sleep_cpu() \

do { \

__asm__ __volatile__ ( "sleep" "\n\t" :: ); \

} while(0)
#endif


Ich verstehe nicht was die genau macht.. Asm ist nicht meins!

Hiermit konfiguriere ich die Module die später im SleepMode mal nicht laufen sollen.
Rufe ich nur diese beiden auf, klappt der SleepMode nicht.. Rufe ich die oben genannte Funktion zum Schluss auf, geht er in den Tiefschlaf.



CodeBox C
void xmega_set_sleep(enum sleep_mds sleep_mde)

{
PR.PRGEN = (USB_MODULE|AES_MODULE|EBI_MODULE|RTC_MODULE|EVSYS_MODULE|DMA_MODULE);
PR.PRPA = (DAC_MODULE|ADC_MODULE|AC_MODULE);
PR.PRPB = (DAC_MODULE|ADC_MODULE|AC_MODULE);
PR.PRPC = (TWI_MODULE|USART1_MODULE|USART0_MODULE|SPI_MODULE|HIRES_MODULE|TC1_MODULE|TC0_MODULE);
PR.PRPD = (TWI_MODULE|USART1_MODULE|USART0_MODULE|SPI_MODULE|HIRES_MODULE|TC1_MODULE|TC0_MODULE);
PR.PRPE = (TWI_MODULE|USART1_MODULE|USART0_MODULE|SPI_MODULE|HIRES_MODULE|TC1_MODULE|TC0_MODULE);
PR.PRPF = (TWI_MODULE|USART1_MODULE|USART0_MODULE|SPI_MODULE|HIRES_MODULE|TC1_MODULE|TC0_MODULE);

SLEEP.CTRL = (STANDBY_MODE_gc); 

}

void xmega_sleep(void)

{
SLEEP.CTRL = (1<<SLEEP_SEN_bp);

}

 
Mit dem SEN Bit im Control Register, geht der Mikcrocontroller erst mal nicht in den SleepMode. Das ist nur ein Enable Bit für den SleepMode.

Du gehst normalerweise so vor:
(1) Sleep Mode konfigurieren
(2) SEN Bit setzen und direkt danach
(3) sleep_cpu() ausführen (Assembler sleep instruction wird ausgeführt)
nun ist der Controller im Sleep Mode
aufwachen:
(4) SEN Bit löschen
 
Den SLEEP-Mode aktivierst Du mit Opcode: 1001010110001000.
Unter Assembler erledigt das das SLEEP-Mnemonic, unter Hochsprachen wirds äquivalente Instructionen geben.
SLEEP löst jedenfalls den gewählten Sleep-Mode aus.
Der Sleep-Mode selbst wird über spezielle Bits in einem entsprechenden Register festgelegt - bei dem von Dir wahrscheinlich (?) verwendeten ATXMega256a3bu sind das die Bits SMODE2,1,0 im Sleep Control Register. Außerdem muß dort das Sleep Enable Bit (SEN) gesetzt werden.
SLEEP greift in das CLOCK-System ein, hält bestimmte Clocks an, die eher den Controller selbst betreffen Speicher, Programmablauf usw.

Konkrete (autarke) Hardware-Module lassen sich über die Power Reduction Register "abklemmen"...

Das geschieht (hier) in entsprechenden Bits des PRGEN (General Power Reduction Register), sowie in den sechs Power Reduction Port Registern A..F.

Edit: Dirk war schneller...
 
Soweit alles klar, hat auch funktioniert..
Nur das mit dem Assembler teil verstehe ich noch nicht wirklich..

Was wäre denn das Kommando hier in GCC?
Wenn ich keinen Assembler kann, bin ich an dieser Stelle (ohne sleep.h) aufgeschmissen oder wie?
 
Wenn ich keinen Assembler kann
Wie gesagt: Die ASM-Instruction lautet "SLEEP"
diese kannst Du als Inline-Assembler einbinden (auch ohne inkludierter Sleep.h).
Vorher muß wie gesagt der Mode festgelegt, und die Ausführung von Sleep freigegeben werden.
Auf die entsprechenden I/O-Register hast Du Zugriff (die werden ja über die io.h eingebunden - wie das mit den einzelnen Bits ist, weiß ich nicht. die Sleepmodes existieren da als Enumeration, fehlt nur noch das SEN-Bit.
@Dirk : Es gibt keinen SLEEP-Befehl in C???

Dann sollte es doch aber trotzdem so gehen

CodeBox C
SLEEP.CTRL=(SLEEP_SMODE_STDBY_gc|1);
__asm__ __volatile__ ( "sleep" "\n\t" :: );

Zeile eins setzt im Sleep-Control-Register die beiden Bits SMODE2 und SMODE1 (SLEEP_MODE_STDBY_gc = 1<<SMODE2|1<<SMODE1 = 12) und SEN (SEN= Bit0 = 1<<0 = 1). Es wird also der Standby gewählt und der Sleep grundsätzlich enabled.
Zeile zwei baut den Opcode des ASM-Befehls SLEEP ein.
Fertig.
 
@Dirk : Es gibt keinen SLEEP-Befehl in C???

Jain.

Ein SLEEP gibt es bei Ansi C/C++ nicht, also nein.

Aber in sleep.h wurde hierfür eine Routine/Macro geschrieben sleep_cpu(), also ja.

Wenn man sleep.h nicht nutzen möchte und das selber nicht mit Inlineassembler lösen kann, hat man ein Problem. Aber wieso sollte man sleep.h nicht nutzen.
Das wäre so, wie würde ich in Assembler programmieren und möchte aber keine Instructions mit Anfangsbuchstaben a und s nutzen wollen und kann für die fehlenden Instructions den Opcode nicht erzeugen. ;)

Hier und da wird immer mal Assembler verwendet, vom Assembler merkt man aber nichts.
sei() und cli() in avr/interrupt.h zum Beispiel.



CodeBox C
#define sei()  __asm__ __volatile__ ("sei" ::: "memory")
#define cli()  __asm__ __volatile__ ("cli" ::: "memory")
 

Über uns

  • Makerconnect ist ein Forum, welches wir ausschließlich für einen Gedankenaustausch und als Diskussionsplattform für Interessierte bereitstellen, welche sich privat, durch das Studium oder beruflich mit Mikrocontroller- und Kleinstrechnersystemen beschäftigen wollen oder müssen ;-)
  • Dirk
  • Du bist noch kein Mitglied in unserer freundlichen Community? Werde Teil von uns und registriere dich in unserem Forum.
  •  Registriere dich

User Menu

 Kaffeezeit

  • Wir arbeiten hart daran sicherzustellen, dass unser Forum permanent online und schnell erreichbar ist, unsere Forensoftware auf dem aktuellsten Stand ist und der Server regelmäßig gewartet wird. Auch die Themen Datensicherheit und Datenschutz sind uns wichtig und hier sind wir auch ständig aktiv. Alles in allem, sorgen wir uns darum, dass alles Drumherum stimmt :-)

    Dir gefällt das Forum und unsere Arbeit und du möchtest uns unterstützen? Unterstütze uns durch deine Premium-Mitgliedschaft!
    Wir freuen uns auch über eine Spende für unsere Kaffeekasse :-)
    Vielen Dank! :ciao:


     Spende uns! (Paypal)