AVR ATtiny Stromaufnahme

#7419999
Lesenswert?

Hallo,

meine Messergebnisse stimmen nicht mit den Datenblatt-Werten überein. Konkret geht es um die Stromaufnahme vom Mikrocontroller im Ruhemodus, wenn nur der Oszillator mit Prescaler und der TCB laufen. (getestet am ATtiny402 @ 3.0V, 21°C)

1
-------------------------------------
2
Datasheet:
3
OSC20M (1MHz system clock): 125 µA
4
TCB @ 1 MHz:                  7.5 µA
5
-------------------------------------

Zusammen: 132.5µA

Gemessen: 235µA

Irgendwas stimmt also nicht. Wo ist der Fehler?

1
// OSC20M: 16MHz
2
// Main Clock: 1MHz
3
#include <avr/io.h>
4
#include <avr/sleep.h>
5

6
int main(void)
7
{
8
  _PROTECTED_WRITE(CLKCTRL.MCLKCTRLB, CLKCTRL_PDIV_16X_gc | CLKCTRL_PEN_bm);   // 1 MHz Main Clock
9

10
  PORTA.PIN1CTRL = PORT_ISC_INPUT_DISABLE_gc;      // disable PA1 digital input buffer
11
  PORTA.PIN2CTRL = PORT_ISC_INPUT_DISABLE_gc;      // disable PA2 digital input buffer
12
  PORTA.PIN3CTRL = PORT_ISC_INPUT_DISABLE_gc;      // disable PA3 digital input buffer
13
  PORTA.PIN6CTRL = PORT_ISC_INPUT_DISABLE_gc;      // disable PA6 digital input buffer
14
  PORTA.PIN7CTRL = PORT_ISC_INPUT_DISABLE_gc;      // disable PA7 digital input buffer
15

16
  TCB0.CCMP = 0xC350;                              // count value
17
  TCB0.CTRLA = TCB_RUNSTDBY_bm | TCB_ENABLE_bm;    // enable Run in Standby, enable TCB
18

19
  SLPCTRL.CTRLA = SLPCTRL_SMODE_STDBY_gc;          // select STANDBY sleep mode
20

21
  while(1)
22
  {
23
    sleep_mode();
24
  }
25
}
#7420012
Lesenswert?

Eventuell am drumherum?

Es kommen jetzt die üblichen Fragen. Wie hast du gemessen, nur den µC? Was ist sonst noch dran, vielleicht fließt ja dein Strom aus einem IO-Port?

Günstig ist wie immer auch ein Schaltplan. Und bei Low-Power besser den kompletten, in eine Prinzip/Übersichtsschaltung passiert es schnell das der verursachende Teil weggelassen wurde (ach ist doch nur die LED oder so)

Bitte nicht missverstehen, ich bin Elektroniker, das sind die für mich wesentlichen Fragen. Die deri Softwarezeilen versteht jemand anderes besser.

#7420137
Lesenswert?

Und überprüfe, ob dein Tiny auch dauerhaft im Sleep-Mode ist, oder ständig aufwacht.

Wakeup-Sources sind ja eigentlich keine aktiv, oder?

Also statt

1
while(1) {
2
    sleep_mode();
3
  }

ein

1
  sleep_mode();
2
  while(1);

dann sollte das am Stromverbrauch deutlich sichtbar sein.

#7420328
Lesenswert?

Mache die IO Pins mal alle als Output Low. Schau wie sich der Stromverbrauch ändert bei anderem Takt oder anderen Einstellungen (bleibt der Differenzbetrag gleich, oder skaliert er). Du kommst ja schonmal im Powerdown auf deine unter 1µA. Ich würde vermuten, dass du eine Brücke irgendwo hast. Guck mal wie viel Strom beim Pullup fließen würde, wenn man den kurzschließen würde. Ich hatte das Problem auch, aber mit einem 2-series im QFN. Da war ein Pin mit GND kurzgeschlossen, Lötfehler.

Du hast 100µA Differenz, Pullups werden mit 35kOhm angegeben (20-50kOhm), wären bei 3V irgendwas um die 80µA, also durchaus passend.

#7420421
Lesenswert?

an Georg M.:

Wie es bei Ihrem ATtiny402 aussieht, kann ich natürlich nicht sagen; bei meinem ATmega4809 verstehe ich den Unterschied in den beiden Datenblattangaben nicht, siehe Anhang. Idle-Modus (entspricht Standby mit aktivem TCB) bei 3.0 V und 5 MHz benötigt hier 520 uA, das passt so ungefähr zu den angegebenen 0.4 mA; aber welche Bedeutung dann die 130 uA haben ... ?

Angehängte Dateien:
#7420439
Lesenswert?

Hallo,

habe auch gemessen. ATmega4808 TQFP auf Adapter auf Steckbrett. An der Stiftleiste sind direkt 2x 100nF Keramik verlötet an Vcc und Avcc. Sonst nichts. 5V über Multimeter auf Steckbrett. Ich messe 2,4µA. Allerdings zeigen alle 3 Multimeter Minus an. Also -2,4µA. Wobei die Kabel richtig herum gesteckt sind. Im Nicht Sleep Mode passt auch alles.

Keysight U1233A Voltcraft VC940 Voltcraft VC220

Mit internal 32kHz keine Änderung.

1
#define F_CPU 1000000UL
2
#include <avr/io.h>
3
#include <avr/sleep.h>
4

5
void set1MHz (void)
6
{
7
    CPU_CCP = CCP_IOREG_gc;
8
    CLKCTRL_MCLKCTRLA = 0;           // 16MHz internal 
9
    CPU_CCP = CCP_IOREG_gc;
10
    CLKCTRL_MCLKCTRLB = CLKCTRL_PDIV_16X_gc | CLKCTRL_PEN_bm;  
11
}
12

13
int main(void)
14
{  
15
    set1MHz();
16
    PORTA.DIR = 0xFF;
17
    PORTC.DIR = 0x0F;
18
    PORTD.DIR = 0xFF;
19
    PORTF.DIR = 0x7F;
20
     
21
    set_sleep_mode(SLEEP_MODE_PWR_DOWN);
22
    //sleep_cpu();
23
    sleep_mode();
24
    sleep_enable();  // überflüssig ???
25
    while (1) 
26
    { }
27
}
#7420444
Lesenswert?

Hallo,

@ TO & Herr Landolt

ich hatte ein paar komische Effekte beim Messen. Programmiere mal deinen Controller für Sleep Mode, trenne die Versorgung, stelle Multimeter auf µA und Verbindung wieder herstellen. Ich hatte auch im µA Meßbereich Probleme mit dem flashen. Signatur wurde nicht erkannt usw. Weil ich hatte auch öfters um die 480µA gemessen was viel zu hoch war. Als wenn der Controller nicht im Sleep Mode war.

Gast #7420448
Lesenswert?

Mangels passender Messgeräte mache ich das so:

In Reihe zur Stromversorgung liegt ein 1 kΩ Widerstand, der zunächst überbrückt ist. Das Programm auf dem µC legt ihn Schlafen. Das sehe ich deutlich an der "Ampere" Anzeige des Netzteils.

Dann entferne ich die Brücke über dem Widerstand und messen den Spannungsabfall.

#7420451
Lesenswert?

set_sleep_mode(SLEEP_MODE_PWR_DOWN);

Okay, aber das war ja unbestritten; da messe ich, wie geschrieben, unter 0.2 uA. Es geht um die Relevanz dieser Angabe für den '16/20 MHz Oscillator (OSC20M)' - die ist für mich als Anwender, nach derzeitigem Kenntnisstand, so interessant wie, sagen wir mal, Länge&Breite irgendeiner Leiterbahn auf dem Chip.

komische Effekte beim Messen

hatte ich nicht (zugegeben, einmal falsch abgelesen). Alles passte zusammen, auch bei dem 'AVR128DB48 Curiosity Nano', das ich schließlich auch noch hervorkramte: die Stromangabe für den isolierten Oszillator ist nur ein (Bruch-) Teil der Wahrheit.

#7420460
Lesenswert?

Programmiere ... trenne ... stelle ... wieder herstellen

Das wird bei mir nichts bringen - irgendwelche Effekte dabei hängen sicher (auch) von Programmiergerät und Stromversorgung ab: das ist bei mir alles Eigenbau.

Das Problem auf eine Frage reduziert: Unter welchen Voraussetzungen kann der Anwender diese '130 uA' messen?

#7420484
Lesenswert?

S. L. schrieb:

Wie es bei Ihrem ATtiny402 aussieht, kann ich natürlich nicht sagen; bei meinem ATmega4809 verstehe ich den Unterschied in den beiden Datenblattangaben nicht, siehe Anhang. Idle-Modus (entspricht Standby mit aktivem TCB) bei 3.0 V und 5 MHz benötigt hier 520 uA, das passt so ungefähr zu den angegebenen 0.4 mA; aber welche Bedeutung dann die 130 uA haben ... ?

Ja, etwas stimmt nicht.

Entweder braucht der TCB viel mehr Strom als angegeben, oder er läuft nicht allein. Oder könnte es andere Erklärungen geben?

Auszüge aus dem Datenblatt:

Three sleep modes: • Idle with all peripherals running • Standby (configurable operation of selected peripherals) • Power-Down with full data retention

TCBn is, by default, disabled in Standby sleep mode. It will be halted as soon as the sleep mode is entered. The module can stay fully operational in the Standby sleep mode if the Run Standby (RUNSTDBY) bit in the TCBn.CTRLA register is written to ‘1’.

#7420488
Lesenswert?

Ich stelle mir das so vor: der isolierte Oszillator läuft mit den angegebenen 125 uA (bzw. 130 oder 160), nur - die Frequenz muss über weite Teile des Chips verteilt werden, das zehrt; deshalb auch das deutlich schlechtere Verhältnis zum gemessenen Strom beim ATmega4809 im Vergleich zum ATtiny402.

#7420495
Lesenswert?

Hallo,

ich denke man muss das anders betrachten. Das ist nicht die absolute Stromaufnahme, sondern der Wert um den es sich reduziert wenn man Einheit x abschaltet bzw. zunimmt beim aktivieren. Laut Angabe im Datenblatt ist das alles im Idle Sleep Mode.

ATmega4808 @5V @1MHz

1
// 677µA
2
set_sleep_mode(SLEEP_MODE_IDLE);
3
TCB0.CTRLA = TCB_RUNSTDBY_bm | TCB_ENABLE_bm;  
4
TCB1.CTRLA = TCB_RUNSTDBY_bm | TCB_ENABLE_bm;        
5
sleep_mode();
1
// 677µA
2
set_sleep_mode(SLEEP_MODE_IDLE);
3
TCB0.CTRLA = TCB_ENABLE_bm;  
4
TCB1.CTRLA = TCB_ENABLE_bm;        
5
sleep_mode();
1
// 652µA
2
set_sleep_mode(SLEEP_MODE_IDLE);
3
TCB0.CTRLA = TCB_RUNSTDBY_bm;
4
TCB1.CTRLA = TCB_RUNSTDBY_bm;     
5
sleep_mode();
1
// 652µA
2
set_sleep_mode(SLEEP_MODE_IDLE); 
3
sleep_mode();
#7420737
Lesenswert?

S. L. schrieb:

die Frequenz muss über weite Teile des Chips verteilt werden, das zehrt

Ja, absolut richtig. Jetzt begreife ich es auch. Es war schon klar, dass das Taktsignal nicht ganz ohne Energieaufwand weitergeleitet werden kann. Überraschend ist dabei aber, dass diese "dunkle" Stromaufnahme rund 20-mal höher liegt als der eigentliche Energiebedarf des 16-bit-Zählers.

#7420758
Lesenswert?

... 20-mal höher ...

Ich denke nicht. Die 7.5 uA des TCB sind bei unserer Betrachtung vernachlässigbar. Der Timer benötigt einen Takt, deshalb bleibt der Oszillator trotz Stand-by-Modus eingeschaltet, was konkret dann dem Idle-Modus entspricht, strommäßig. Es geht um die Differenz zwischen der Datenblattangabe von 125 uA für den Oszillator und dem gemessenen Wert von 235 im Betrieb - die erkläre ich mir damit, dass die Verteilung des Oszillatorsignals über den Chip zusätzlichen Strom benötigt, und je größer der Chip, wie bei meinen ATmega4809 bzw. AVR128DB28, umso mehr: ATtiny402: +80 %, ATmega4809: +110 %, AVR128DB28: +240 %.

#7420810
Lesenswert?

S. L. schrieb:

Die 7.5 uA des TCB sind bei unserer Betrachtung vernachlässigbar.

Welchen Sinn hat dann die Datenblatt-Angabe über die Stromaufnahme vom TCB, wenn sie nur einen kleinen Bruchteil des Unvermeidbaren ausmacht?

S. L. schrieb:

Der Timer benötigt einen Takt, deshalb bleibt der Oszillator trotz Stand-by-Modus eingeschaltet, was konkret dann dem Idle-Modus entspricht, strommäßig. Es geht um die Differenz zwischen der Datenblattangabe von 125 uA für den Oszillator und dem gemessenen Wert von 235 im Betrieb - die erkläre ich mir damit, dass die Verteilung des Oszillatorsignals über den Chip zusätzlichen Strom benötigt

Beim Oszillator allein (für diesen Test auf 16MHz umgeschaltet) messe ich nur 95µA @ 3V. Der Rest ist für den TCB und die Taktzufuhr. Sonst ist nichts eingeschaltet und muss also nicht mit dem Oszillatorsignal beliefert werden. Theoretisch.

#7421014
Lesenswert?

Beim Oszillator allein (für diesen Test auf 16MHz umgeschaltet) messe ich nur 95µA @ 3V. Der Rest ist für den TCB und die Taktzufuhr.

Das heißt, 140 uA (235-95) für den TCB? Erstaunlich, wirklich ganz erstaunlich. Dass der Winzling sich so anders verhält! Zum Vergleich:

1
3.0 V, 4 MHz
2
            idle [uA]   +TCB0 [uA]
3
ATmega4809   492          514
4
AVR128DA28   628          643
5
AVR128DB28   559          572
6
AVR128DB48   564          577

Hier ist der TCB vernachlässigbar.

#7421027
Lesenswert?

S. L. schrieb:

Das heißt, 140 uA (235-95) für den TCB? Erstaunlich

Nein, das heißt, 7µA für den TCB und 133µA für die "dunkle Materie".

Oszillator allein (ATtiny402, 16MHz):

1
#include <avr/io.h>
2
#include <avr/sleep.h>
3

4
int main(void)
5
{
6
  _PROTECTED_WRITE(CLKCTRL.MCLKCTRLB, CLKCTRL_PDIV_16X_gc | CLKCTRL_PEN_bm);   // 1 MHz main clock
7
  _PROTECTED_WRITE(CLKCTRL.OSC20MCTRLA, CLKCTRL_RUNSTDBY_bm);                  // Run in Standby
8

9
  PORTA.PIN1CTRL = PORT_ISC_INPUT_DISABLE_gc;   // disable PA1 digital input buffer
10
  PORTA.PIN2CTRL = PORT_ISC_INPUT_DISABLE_gc;   // disable PA2 digital input buffer
11
  PORTA.PIN3CTRL = PORT_ISC_INPUT_DISABLE_gc;   // disable PA3 digital input buffer
12
  PORTA.PIN6CTRL = PORT_ISC_INPUT_DISABLE_gc;   // disable PA6 digital input buffer
13
  PORTA.PIN7CTRL = PORT_ISC_INPUT_DISABLE_gc;   // disable PA7 digital input buffer
14

15
  SLPCTRL.CTRLA = SLPCTRL_SMODE_STDBY_gc;       // select STANDBY sleep mode
16

17
  while(1)
18
  {
19
    sleep_mode();
20
  }
21
}

Messergebnis: 95µA @ 3.0V.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren