Willkommen in unserer Community

Werde Teil unserer Community und registriere dich jetzt kostenlos ...

  1. Diese Seite verwendet Cookies. Wenn du dich weiterhin auf dieser Seite aufhältst, akzeptierst du unseren Einsatz von Cookies. Weitere Informationen

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

Dieses Thema im Forum "Software" wurde erstellt von Janiiix3, 2. Juni 2017.

  1. Janiiix3

    Janiiix3 Mitglied

    Registriert seit:
    28. September 2013
    Beiträge:
    929
    Zustimmungen:
    3
    Ort:
    Hannover
    Sprachen:
    C#
    Map
    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 und 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 und 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);
    
    }
    
    
     
  2. Dirk

    Dirk Administrator Mitarbeiter

    Registriert seit:
    28. Januar 2007
    Beiträge:
    3.962
    Zustimmungen:
    98
    Ort:
    Mittelhessen, Giessen
    Sprachen:
    C#, Assembler, Pascal, C++, PHP, Java
    Map
    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
     
  3. LotadaC

    LotadaC Sehr aktives Mitglied

    Registriert seit:
    22. Januar 2009
    Beiträge:
    2.565
    Zustimmungen:
    29
    Ort:
    Hennigsdorf
    Sprachen:
    BascomAVR, Assembler
    Map
    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...
     
  4. Janiiix3

    Janiiix3 Mitglied

    Registriert seit:
    28. September 2013
    Beiträge:
    929
    Zustimmungen:
    3
    Ort:
    Hannover
    Sprachen:
    C#
    Map
    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?
     
  5. Dirk

    Dirk Administrator Mitarbeiter

    Registriert seit:
    28. Januar 2007
    Beiträge:
    3.962
    Zustimmungen:
    98
    Ort:
    Mittelhessen, Giessen
    Sprachen:
    C#, Assembler, Pascal, C++, PHP, Java
    Map
    Ja.

    Aber warum solltest du sleep.h nicht verwenden sollen oder wollen? :hmmmm:
     
  6. LotadaC

    LotadaC Sehr aktives Mitglied

    Registriert seit:
    22. Januar 2009
    Beiträge:
    2.565
    Zustimmungen:
    29
    Ort:
    Hennigsdorf
    Sprachen:
    BascomAVR, Assembler
    Map
    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 und 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.
     
  7. Dirk

    Dirk Administrator Mitarbeiter

    Registriert seit:
    28. Januar 2007
    Beiträge:
    3.962
    Zustimmungen:
    98
    Ort:
    Mittelhessen, Giessen
    Sprachen:
    C#, Assembler, Pascal, C++, PHP, Java
    Map
    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 und C++
    #define sei()  __asm__ __volatile__ ("sei" ::: "memory")
    #define cli()  __asm__ __volatile__ ("cli" ::: "memory")
     

Diese Seite empfehlen

  • Über uns

    Unsere immer weiter wachsende Community beschäftigt sich mit Themenbereichen rund um Mikrocontroller- und Kleinstrechnersysteme. Neben den Themen Design von Schaltungen, Layout und Software, beschäftigen wir uns auch mit der herkömmlichen Elektrotechnik.

    Du bist noch kein Mitglied in unserer freundlichen Community? Werde Teil von uns und registriere dich in unserem Forum.
  • Coffee Time

    Unser makerconnect-Team arbeitet hart daran sicherzustellen, dass unser Forum permanent online und schnell erreichbar ist, unsere Forensoftware auf dem aktuellsten Stand ist und unser eigener makerconnekt-Server regelmäßig gewartet wird. Wir nehmen das Thema Datensicherung und Datenschutz sehr ernst und sind hier sehr aktiv, auch sorgen wir uns darum, dass alles Drumherum stimmt!

    Dir gefällt das Forum und die Arbeit unseres Teams und du möchtest es unterstützen? Unterstütze uns durch deine Premium-Mitgliedschaft, unser Team freut sich auch über eine Spende für die Kaffeekasse :-)
    Vielen Dank!
    Dein makerconnect-Team

    Spende uns! (Paypal)