Forum: Mikrocontroller und Digitale Elektronik ATMega32U4 power down: komme nicht auf <1mA


von Helge (Gast)


Lesenswert?

Hi,


ich versuche gerade, auf einer Platine die schlimmsten Stromverbraucher 
zu lokalisieren, da letztlich alles von einer LiIon-Zelle laufen soll. 
Der ATMega32U4 @3.3V soll letztlich in power down versetzt werden und 
~1µA ziehen.

Es befanden sich eine 3.6V Zenerdiode und ein LM3940 LDO zusammen mit 
einer Baugruppe, welche über einen FET abgeschaltet werden kann, auf der 
Platine. Diese sind nun herausgelötet bzw. deaktiviert, dennoch fließen 
über 4mA. Bevor ich weiter Leiterbahnen auftrenne, dachte ich, ich frag 
mal:
1
int main (void)
2
{  
3
  cli();
4
  wdt_disable();
5
  
6
  power_adc_disable();
7
  power_usart0_disable();
8
  power_spi_disable();
9
  power_twi_disable();
10
  power_timer0_disable();
11
  power_timer1_disable();
12
  power_timer2_disable();
13
  power_timer3_disable();
14
  power_usart0_disable();
15
  power_usart1_disable();
16
  power_usb_disable();  // turn off USB transceiver
17
  USBCON |= (1 << FRZCLK);   // Freeze the USB Clock
18
  PLLCSR &= ~(1 << PLLE);  // Disable the USB Clock (PPL)
19
  USBCON &= ~(1 << USBE);  // Disable the USB
20
  
21
  
22
  /*Der AVR-GCC enthält leider das Macro sleep_mode(), welches sehr
23
  gefährlich ist, da es in den meisten Fällen unerwünschte Nebeneffekte
24
  hat.
25
  Diese Macro greift nämlich nicht atomar auf das MCUCR zu, was in
26
  größeren Programmen Probleme geben kann und wird.
27
  Außerdem folgt das SLEEP nicht direkt auf das SEI einer vorhergehenden
28
  atomaren Operation zum Aktivieren des Aufwachinterrupts.
29
  Deshalb sollte man auf dieses Macro unbedingt verzichten!*/
30
  
31
  
32
  set_sleep_profile(SLEEP_MODE_PWR_DOWN);
33
34
  sleep_enable();
35
  sei();
36
  sleep_cpu();
37
38
  return 0;
39
}

fuses (siehe http://www.engbedded.com/fusecalc/):
avrdude.exe -c usbtiny -p m32u4 -U lfuse:w:0xed:m -U hfuse:w:0xd9:m -U 
efuse:w:0xff:m

(BOD deaktiviert)

Habe ich etwas übersehen, gibt es einen bug in den Bibliotheken ?

Ich nutze Atmel Studio 6 mit:

Installed Packages: AVRGCC - 3.4.1.95
AVR Toolchain 8 Bit
Version: 3.4.1.830 - GCC  4.6.2


Ich hoff ihr könnt mir da weiterhelfen. Der Systemtakt ist jedenfalls 
aus, das habe ich als erstes auf dem Oszi angeschaut.

von Falk B. (falk)


Lesenswert?

Siehe Sleep Mode.

Keine floatenden Eingänge? Alle Lasten an den Ausgängen abgeschaltet?

von Walter S. (avatar)


Lesenswert?

vielleicht versorgst du andere ICs über eine Datenleitung des AVR,
Schaltplan?

von Helge (Gast)


Lesenswert?

Ich habe eben mit einem fast leeren Testboard den obigen code 
ausprobiert. Das einzige, was jetzt noch dranklemmt, ist die externe 
Referenz des AD-Wandlers. Irgendetwas verpasse ich hier...

von Peter II (Gast)


Lesenswert?

Helge schrieb:
> ch habe eben mit einem fast leeren Testboard den obigen code
> ausprobiert. Das einzige, was jetzt noch dranklemmt, ist die externe
> Referenz des AD-Wandlers. Irgendetwas verpasse ich hier...

also Hängen die anderne IOs in der Luft? Wenn ja schalte mal den Pullup 
ein oder die IOs als ausgang.

von MR. Ohm (Gast)


Lesenswert?

Schaltplan?
Hoffentlich den Programmer abgesteckt sonst brauchst du gar nicht 
messen.

von Helge (Gast)


Lesenswert?

im power down Modus sollten die Porttreiber deaktiviert sein. Ich habe 
ausprobiert:

* output low: Stromverbrauch durch pull-ups an manchen pins (10.9mA)
* output high: 4.x mA
* output tri-state (input): 4.x mA

Nach Abtrennen der Versorgung über die 3.3V rail zeigt auch Vref des 
AD-Wandlers einen hochohmigen pin.

Ich habe alle pins durchgemessen.. bis auf die Versorgungspins hängen 
alle in der Luft.

von Peter II (Gast)


Lesenswert?

Helge schrieb:
> * output low: Stromverbrauch durch pull-ups an manchen pins (10.9mA)

dann muss aber noch etwas dran hängen, wohin sollen denn die 10mA 
fließen. Es darf auf jeden Fall mit pullUps nicht mehr werden wenn 
nichts dran hängt.

von Helge (Gast)


Lesenswert?

Bisher schließe ich nur daraus, dass die ports nicht korrekt deaktiviert 
werden.

Ich habe auch versucht, mich an folgendem Beispiel zu orientieren:
http://harizanov.com/2013/02/power-saving-techniques-on-the-atmega32u4/

dort erreicht man schon im Betrieb niedrigere Ströme seufz

von Helge (Gast)


Lesenswert?

Desweiteren scheint es keinen Unterschied zwischen den verschiedenen 
Sleep Modes zu geben.

Lege ich den Finger an die Chipseite mit den Clock-Pins, sinkt der Strom 
auf 1.5mA.

????

von Helge (Gast)


Lesenswert?

Setzen der Ports reduziert die Stromaufnahme von 4.4mA auf 3.9mA?
1
  PORTD = 0x00;
2
  DDRD = 0xFF;
3
  
4
  PORTE = 0x00;
5
  DDRF = 0xFF;
6
7
  PORTF = 0x00;
8
  DDRF = 0xFF;
9
  
10
  PORTC = 0x00;
11
  DDRC = 0xFF;
12
  
13
  PORTB = 0xFF;
14
  DDRB = 0xFF;

while(1) verbraucht übrigens weniger Strom als

set_sleep_profile(SLEEP_MODE_PWR_DOWN);
sleep_cpu();

von Anon Y. (anonymous)


Lesenswert?

Wie misst du denn den Strom? Bist du dir sicher, dass die CPU nicht 
abstürzt?

Ich habe hier noch code bei mir gefunden. Keine Ahnung, ob es 
funktioniert:
1
        set_sleep_mode(SLEEP_MODE_PWR_DOWN);            // 3 mikroampere in this mode
2
        sleep_enable();                                                         // takes over the value for sleep mode
3
4
        sleep_cpu();                                                            // really sleeps after the next instruction has been executed
5
        sleep_disable();                                                        // deactivates the set sleep mode

von Timmo H. (masterfx)


Lesenswert?

Misst du zufällig auch den Ruhestrom des Spannungsreglers mit?
Selbst ohne alles auf definierte Pegel zu setzen sollte mit
1
set_sleep_mode(SLEEP_MODE_PWR_DOWN);      
2
sleep_mode();
die reine Stromaufnahme des megas weit unter 500µA liegen

von Maus (Gast)


Lesenswert?

siehe Ultra low power
und   Versorgung aus einer Zelle



was soll set_sleep_profile  ?   wenn ich danach in ggl suche findet sich 
nix.

Helge schrieb:
> /*Der AVR-GCC enthält leider das Macro sleep_mode(), welches sehr
>   gefährlich ist, da es in den meisten Fällen unerwünschte Nebeneffekte
>   hat.
>   Diese Macro greift nämlich nicht atomar auf das MCUCR zu, was in
>   größeren Programmen Probleme geben kann und wird.
>   Außerdem folgt das SLEEP nicht direkt auf das SEI einer vorhergehenden
>   atomaren Operation zum Aktivieren des Aufwachinterrupts.
>   Deshalb sollte man auf dieses Macro unbedingt verzichten!*/

was soll das?  ich hatte noch nie Probleme damit.
Sonst setzte die Flags doch per Hand?!

von Wusel D. (stefanfrings_de)


Lesenswert?

Auch wenn die Ports deaktiviert sind, verbrauchen Sie dennoch Strom, 
sofern ihr Signalpegel im "verbotenen" Bereich zwischen high und low 
liegt. Das gilt auch für die analogen Eingänge.

Deswegen: All I/O Pins mit Pull-Up oder Pull-Down Widerstände 
beschalten.

Man empfieht oft auch, die I/O Pins per Software als Eingang mit Pull-Up 
konfigurieren. Im Power-DOwn Modus geht das aber nicht, weil die 
Pull-Ups dann immer daktiviert sind (soweit ich weiß).

> Lege ich den Finger an die Chipseite mit den Clock-Pins, sinkt der
> Strom auf 1.5mA.

Weil der Finger die Pins auf einen Pegel bringt, der um gültigen Bereich 
liegt (oder näher dran ist).

Im Datenblatt des ATmega8 steht dazu

> If the input buffer is enabled and the input signal is left floating
> or have an analog signal level close to VCC/2, the input buffer will
> use excessive power.

Ich denke, das passiert aber auch in abgeschwächter Form, wenn der input 
Buffer disabled ist.

von Helge (Gast)


Lesenswert?

So, das müsste es tun:
1
  cli();
2
  power_timer0_disable();
3
      
4
        sleep_enable();
5
        set_sleep_mode(SLEEP_MODE_PWR_DOWN);
6
  sei();
7
        sleep_mode();
8
        // ... zzZzzZZzZZZ ...
9
        sleep_disable();
10
11
  cli();
12
  power_timer0_enable();
13
  TCCR0A |= (1<<FOC0A);  
14
  TIFR0  |= (1<<OCF0A);  // clear flag    
15
  EIFR = 0xFF;
16
  sei();

Es fließen noch immer etwa 150µA irgendwo hin, wenn ich es auf 50µA 
schaffe, ist das Thema ohnehin erledigt :-)

Danke an alle, die mir hier geholfen haben!
In set_sleep_profile() wurde ursprünglich set_sleep_mode() aufgerufen 
und die Peripherie für sleep mode umkonfiguriert.

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
Noch kein Account? Hier anmelden.