Ich habe hier einen STM32F030F4P6 (TSSOP20-Gehäuse), mit dem ich gerade
ein paar Versuche mit den Low-Power Modi mache. Speziell interessiert
mich der Stop-Mode.
Laut Datenblatt (siehe Anhang) sollte im Stop-Mode mit dem
Spannungsregler im Low-Power Mode die Stromaufnahme bei max. 32 µA (IDD)
und 3,5 µA (IDDA mit eingeschaltetem VDDA Monitoring) liegen. Insgesamt
also im Worst-Case 35,5 µA.
Zur Aufnahme der Messwerte sagt das Datenblatt folgendes:
[i]The MCU is placed under the following conditions:
• All I/O pins are in analog input mode
• All peripherals are disabled except when explicitly mentioned
• The Flash memory access time is adjusted to the fHCLK frequency:
– 0 wait state and Prefetch OFF from 0 to 24 MHz
– 1 wait state and Prefetch ON above 24 MHz
• When the peripherals are enabled fPCLK = fHCLK
The parameters given in Table 25 to Table 27 are derived from tests
performed under ambient temperature and supply voltage conditions.[/i]
In dem unten angegebenen Code habe ich alle GPIOs im Analog Mode
konfiguriert, mit Ausnahme von GPIOD. Sobald ich in dieses Register
einen Wert schreibe, landet der µC laut Debugger im HardFault_Handler,
vermutlich, weil der F4P6 gar keine PD-Pins hat (PC-Pins hat er aber
eigentlich auch nicht und hier funktioniert alles). Der Flash ist nach
dem Reset standardmäßig mit 0 wait states und Prefetch off konfiguriert.
Alle Takte, die ich während dem Programmablauf aktiviere, deaktiviere
ich vor dem Wechsel in den Stop-Mode wieder.
Wenn ich nun mit einem Multimeter den Strom in VDD + VDDA messe ('A' in
Schaltplanskizze), erhalte ich einen Wert von 155 µA, was mir deutlich
zu viel erscheint. Dazu kommt, dass die Werte, die ich oben aus dem
Datenblatt zitiert habe, als Maximalwerte bei 85°C angegeben sind. Ich
vermute daher, dass irgendwas in meinem Code nicht stimmt und ich doch
noch irgendwo einen Energiefresser habe. Auch ein anderes Multimeter
zeigt einen ähnlichen Wert (150 µA).
Hier der verwendete Code:
1 | #include "stm32f0xx.h"
|
2 |
|
3 | #define WFI 1
|
4 | #define WFE 2
|
5 | #define LOW_POWER 1
|
6 | #define NORMAL 2
|
7 |
|
8 | void PWR_Enter_Stop_Mode(uint8_t mode, uint8_t Regulator_State);
|
9 |
|
10 | int main(void)
|
11 | {
|
12 | //Takt für GPIOs aktivieren
|
13 | RCC->AHBENR |= RCC_AHBENR_GPIOAEN | RCC_AHBENR_GPIOBEN | RCC_AHBENR_GPIOCEN | RCC_AHBENR_GPIODEN | RCC_AHBENR_GPIOFEN;
|
14 |
|
15 | //Alle GPIOs in analogen Modus schalten
|
16 | GPIOA->MODER = 0xFF;
|
17 | GPIOB->MODER = 0xFF;
|
18 | GPIOC->MODER = 0xFF;
|
19 | //GPIOD->MODER = 0xFF; //Springt zu HardFault_Handler im Startup-Code, egal, welcher Wert geschrieben wird
|
20 | GPIOF->MODER = 0xFF;
|
21 |
|
22 | //Takt für GPIOs deaktivieren
|
23 | RCC->AHBENR &= ~(RCC_AHBENR_GPIOAEN | RCC_AHBENR_GPIOBEN | RCC_AHBENR_GPIOCEN | RCC_AHBENR_GPIODEN | RCC_AHBENR_GPIOFEN);
|
24 |
|
25 | PWR_Enter_Stop_Mode(WFI,LOW_POWER);
|
26 |
|
27 | while(1)
|
28 | {
|
29 | }
|
30 | }
|
31 |
|
32 | void PWR_Enter_Stop_Mode(uint8_t Mode, uint8_t Regulator_State) //Wechselt vom Run-Mode in den Stop-Mode
|
33 | {
|
34 | RCC->APB1ENR |= RCC_APB1ENR_PWREN; //Takt für PWR-Einheit aktivieren
|
35 | SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; //SLEEPDEEP-Bit setzen, damit der µC in den Stop-Mode wechselt
|
36 | PWR->CR &= ~PWR_CR_PDDS; //PDDS-Bit löschen, damit in den Stop-Mode gewechselt wird (und nicht in den Standby-Mode)
|
37 | PWR->CR |= PWR_CR_CWUF; //WUF-Flag im PWR_CSR Register löschen, damit der µC nicht direkt wieder aufwacht
|
38 | while((PWR->CSR & PWR_CSR_WUF) == PWR_CSR_WUF); //Warten, bis das Flag gelöscht ist
|
39 |
|
40 | if(Regulator_State == LOW_POWER)
|
41 | {
|
42 | PWR->CR |= PWR_CR_LPDS; //LPDS-Bit setzen, damit der Spannungsregler in einen Low-Power Modus während des Stop-Mode wechselt
|
43 | }
|
44 | else
|
45 | {
|
46 | PWR->CR &= ~PWR_CR_LPDS; //LPDS-Bit löschen, damit der Spannungsregler normal weiterläuft
|
47 | }
|
48 |
|
49 | RCC->APB1ENR &= ~RCC_APB1ENR_PWREN; //Takt für PWR-Einheit deaktivieren
|
50 |
|
51 | if(Mode == WFI)
|
52 | {
|
53 | __WFI(); //Wait for Interrupt
|
54 | }
|
55 | else
|
56 | {
|
57 | __WFE(); //Wait for Event
|
58 | }
|
59 | }
|
Vielleicht kennt sich einer mit den Low-Power Modi des STM32 aus und
weiß, wo der Wurm drin steckt.
Den Stromverbrauch messe ich mit abgestecktem ST-Link, lasse ich den
ST-Link angesteckt, dann liegt der Stromverbrauch bei knapp 800 µA.
Mit WFE erhalte ich dasselbe Ergebnis wie mit WFI.
Danke für eure Antworten.