Electronic – Implementing a low cost battery backup circuit for internal RTC in STM32F030R8


Extension of this question.

Datasheet: http://www.st.com/resource/en/datasheet/stm32f030f4.pdf

The micro-controller in question has an internal RTC module but no VBAT pin. As such, the only way RTC can be given power backup is to use a battery for whole microcontroller, sense the absence of main 3.3V power supply and shut down the micro-controller leaving only RTC running. However there will be external LEDs and other elements present which might draw current from the battery draining it quickly.

Top answerer of that post hinted towards a minimal circuit using diodes. However I couldn't come up with a simple solution. If the circuit is too complicated and/or costly, it might be worthwhile to select another microcontroller which has a VBAT pin.

Is there anything that I can do in this regard?


I am looking at CR2032 battery for this purpose. However I am also leaning towards using a supercapacitor for the same purpose. Max duration of power outage will be 6 hours and I think I can easily find supercaps which will provide power that long. If I fail, CR2032 is the way to go.

Best Answer

Duskwuff suggestion is good, this is the way I'd do it. There are however important information that must be added:

Hardware part

  • It works only if the source of lower priority has a lower voltage than the source of higher priority. For example, it works with a 3.3V input and a 3V lithium battery, but wouldn't work with a 2.5V input and a 3V battery.
  • The diodes must be schottky diodes. And their voltage drop must be considered. Since the MCU you mention consumes a few tens of mA maximum, according to the datasheet, you won't have very high voltage drop. Something like 0.3-0.4V with BAT54, for example. In your application, this is fine because the MCU can work with a supply voltage as low as 2.4V, and because lithium batteries have a very flat discharge curve that don't go lower than 2.8V for low currents (we're really on the limit here, however - a MCU that would accept a supply of 2.0V or lower would be safer).
  • Also put a big cap at the diode cathodes, so it gives you more time, on the software part (see below), to react when main power is removed. For example, something like 100ยต will give you about 2.5ms to go from a supply of 2.9V (3.3 minus diode drop) to 2.4V (the minimum required by the MCU) at ~20mA (a reasonable worst-case consumption of the MCU - check your specific case).

This also has an impact on the external peripheral devices: all LEDs and additional hardware that consume significant power should be powered by the main supply directly (before the diode). So this part of the circuit will be shut down immediately when main power disappears and won't suck the capacitor energy (which would reduce the allowed time for shut down). So that means LEDs shouldn't be directly connected to the MCU pins, but through a transistor (or fet). That also means that you now have two power domains, so there may be a few precautions to take with signals from the MCU that go to the peripheral chips of the "main supply" power domain. There might be a time during which you're still driving some signals from the MCU, that go to powered down peripheral chips. This will have bad consequences (current will flow through the protection diodes of the peripheral chips). At least, you should put series resistors (maybe 1k) on these signals (check the absolute maximum ratings of these peripheral chips). But this will slow these signals down. Therefore, for high-speed signals, another solution is to use an additional stage between power domains. A voltage translator with dual supply and Ioff (partial power-down) is perfect for this (e.g. 74AVC2T45, 74AVC4T245, ...)

Software part

Now, there is one important thing to consider: you must switch the MCU to standby mode ASAP when the main supply disappears. Or the MCU will reset, because if the MCU is busy and consumes a lot of current when the main supply is removed, the backup voltage will experience a higher drop than what can be tolerated, due to the battery internal resistance and the schottky diode.

The above-mentioned capacitor can help with this matter, but you must ensure that you switch before the additional time it gives you. So there are two possible ways to ensure that:

Reading the main supply voltage level with an ADC:

This is what duskwuff suggested (through the resistor divider). This is nice because you can monitor the voltage precisely, and be warned as soon as it starts going down. However, you must regularily sample it with the ADC. So it takes some MCU processing time, because the period between the samplings must be lower than the time the capacitor gives you to shut down.

Reading the main supply voltage as a digital value:

This would require sizing the resistor divider so that, when the input is 3.3V, you have an input voltage above Vih (so the upper resistor is a lot lower than the lower resistor). This way, you can configure the input pin as a digital input that triggers an interrupt. So it doesn't take MCU processing time to monitor the power, you're automatically warned when it disappears. This is nice, but it can work only if the supply disappears very fast (a lot faster than the shutdown time given by the capacitor). Otherwise, you'll be warned only when the supply goes below Vil, and that will be too late: you'll have switched to the battery since a long time without knowing it.

If you're not sure, size the resistors for the digital case, and choose an input pin that can act both as an ADC input or as a GPIO with interrupt capability. This, way, you just have to modify the firmware to go one way or the other.