Forum: Mikrocontroller und Digitale Elektronik STM32 Alarm Register als nicht-flüchtigen Speicher nutzen


von Johannes H. (jhuebner)


Lesenswert?

Hallo zusammen,

ich habe ein Softwareprojekt zum steuern meines E-Autos. 
(https://github.com/jsphuebner/stm32-car/tree/touran-meb). Es läuft auf 
einem STM32F103RBT6.
Da ich einen neuen Akku verbaut habe läuft das jetzt mit dem BMS etwas 
anders, ich muss viele Sachen selbst machen die vorher ein OEM BMS 
gemacht hat.

Eines davon ist die SoC Berechnung anhand der entnommenen Ladung. Das 
klappt soweit alles, nun möchte ich aber den SoC speichern und wenn ich 
das Auto wieder benutze den alten Wert wieder laden.

Ich will vermeiden das interne Flash zu nutzen, weil z.B. beim Löschen 
einer Page der Prozessor kurz Pause macht - beim Fahren eher schlecht.

Nun dachte ich, ich kann das Alarm-Register der RTC quasi als 
gepuffertes SRAM zweckentfremden. Klappt aber nicht, nach einem Neustart 
(egal ob Soft Reset oder Power on Reset) ist der wert wieder auf -1. 
Direkt nach dem Reinschreiben ist der Wert gespeichert, nur eben nach 
dem Neustart nicht.

Beim booten nutze ich von libopencm3 die Funktion
rtc_awake_from_standby() und probeweise auch rtc_auto_awake(RCC_LSE, 
32767) (einmal muss die Clock-Config ja gemacht werden).

Die Funktion macht eigentlich nichts verdächtiges:
1
void rtc_awake_from_standby(void)
2
{
3
        uint32_t reg32;
4
 
5
        /* Enable power and backup interface clocks. */
6
        rcc_periph_clock_enable(RCC_PWR);
7
        rcc_periph_clock_enable(RCC_BKP);
8
 
9
        /* Enable access to the backup registers and the RTC. */
10
        pwr_disable_backup_domain_write_protect();
11
 
12
        /* Wait for the RSF bit in RTC_CRL to be set by hardware. */
13
        RTC_CRL &= ~RTC_CRL_RSF;
14
        while ((reg32 = (RTC_CRL & RTC_CRL_RSF)) == 0);
15
 
16
        /* Wait for the last write operation to finish. */
17
        /* TODO: Necessary? */
18
        while ((reg32 = (RTC_CRL & RTC_CRL_RTOFF)) == 0);
19
}

Die Zeit an sich verhält sich auch wie geplant, sprich die Sekunden 
laufen auch weiter wenn ich die Spannung wegnehme (3V Batterie hängt an 
VBAT, Takt über 32 kHz Quartz). Nur der Alarm-Wert ist weg. Was mache 
ich falsch?

: Bearbeitet durch User
von Steve van de Grens (roehrmond)


Lesenswert?

Was du falsch gemacht hast habe ich nicht erkannt, aber

alternativ kannst du das RAM der RTC nutzen. Das sind einige zig Bytes 
frei für eigene Zwecke.

von Peter D. (pdiener) Benutzerseite


Lesenswert?

Das Alarm Register ist doch eine Interupt source für wakeup. Natürlich 
wird das bei Wechsel in standby erstmal cleared sonst kann es ja nicht 
triggern, oder?

Bau halt ein externes gepuffertes RAM dran. Oder lass die CPU einfach 
laufen, das ist doch bei nem Auto mit zig kWh Batterie einfach egal.

von Steve van de Grens (roehrmond)


Lesenswert?

Peter D. schrieb:
> Bau halt ein externes gepuffertes RAM dran

Wozu das? Der STM32F103RBT6 hat das wie gesagt doch schon intern.

Da ich nun zu hause bin konnte ich in meine Notizen schauen. Im 
Reference Manual wird das "Backup Register" genannt. 10 Stück mit je 16 
Bit gibt es, die ersten 9 davon sind frei verwendbar.

: Bearbeitet durch User
von Johannes H. (jhuebner)


Lesenswert?

Wie cool ist das denn, jetzt programmiere ich den STM schon seit 13 
Jahren und habe die so lange übersehen...
Vielen Dank, damit gehts auf jeden Fall.

Ich will auf jeden Fall 0 Verbrauch wenn das Auto aus ist. Dann wird 
auch die 12V Batterie nicht nachgeladen und wenn die leer ist ziehen die 
Hauptschütze nicht mehr an ;)

von Johannes H. (jhuebner)


Lesenswert?

So, habe das jetzt ausprobiert und es funktioniert wie erwartet :)
1
BKP_DR1 = Param::GetInt(Param::nvval);

schreibt rein und
1
Param::SetInt(Param::nvval, BKP_DR1);

Liest es beim Start wieder ein. Laut Manual gibt es sogar 42 davon. 
Warum gerade 42? hmm.

Ich denke es ist wichtig, dass ich vorher die RTC initialisiere weil 
dadurch wird erst der Zugriff in die "Backup Domain" möglich.

Vielen Dank nochmal für den Tipp.

: Bearbeitet durch User
von Hans-Georg L. (h-g-l)


Lesenswert?

Johannes H. schrieb:
> So, habe das jetzt ausprobiert und es funktioniert wie erwartet :)
>
>
1
BKP_DR1 = Param::GetInt(Param::nvval);
>
> schreibt rein und
>
>
1
Param::SetInt(Param::nvval, BKP_DR1);
>
> Liest es beim Start wieder ein. Laut Manual gibt es sogar 42 davon.
> Warum gerade 42? hmm.
>

42 = 101010b Das ist in einem Binärsystem nichts ungewöhnliches, das 
wusste auch schon "Deep Thought" ;-)

> Ich denke es ist wichtig, dass ich vorher die RTC initialisiere weil
> dadurch wird erst der Zugriff in die "Backup Domain" möglich.
>
> Vielen Dank nochmal für den Tipp.

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Mein Auto schreibt sowas in ein externes EEPROM. Gut, das ist auch noch 
ein 80C535 MC, aber auch beim STM32F100 habe ich so eine Lösung 
bevorzugt. Der hält dann auch noch andere Dinge, wie Hodometer und 
Tageskilometer, sowie Kapazität für jeden Batterieblock.

von Steve van de Grens (roehrmond)


Lesenswert?

Johannes H. schrieb:
> Liest es beim Start wieder ein. Laut Manual gibt es sogar 42 davon.
> Warum gerade 42?

In meinem steht eine andere Anzahl. Die Anzahl der Backup Register 
variiert je nach STM32 Modell. Bist du sicher, ins richtige Reference 
Manual geschaut zu haben?

: Bearbeitet durch User
von Johannes H. (jhuebner)


Lesenswert?

Bin ich sicher, aber habe es nicht alles durchgelesen:
1
20-byte data registers (in medium-density and low-density devices) or 84-byte data
2
registers (in high-density, XL-density and connectivity line devices)

also sinds beim F103 nur 10 Register

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.