🛠 Sommeil profond Stop et réveil par RTC
Objetivos
Dividir el consumo por mil: sumergir el GD32F103 en modo Stop (núcleo y relojes APB detenidos, SRAM conservada) y despertarlo periódicamente con la RTC. Orden de magnitud indicado por la hoja de datos: aproximadamente 5,6 a 5,8 µA en standby con RTC activa, y un despertar en unos pocos microsegundos desde el sleep. Aprenderá la jerarquía Sleep/Stop/Standby, el papel de VBAT e IRC40K (o LXTAL 32,768 kHz), y la trampa del retorno a IRC8M tras el despertar.
Material
- Tarjeta GD32F103C8T6 / CBT6 compatible Blue Pill; para medir los µA, retirar el LED y el regulador de la tarjeta (o utilizar una core board desnuda) y un microamperímetro en serie con la alimentación de 3,3 V
- RTC alimentada continuamente: fuente IRC40K interna (no se requiere cristal) o LXTAL 32,768 kHz si está poblado; VBAT de 1,8-3,6 V posible con pila de botón
- LED PC13 (activo-LOW) para visualizar los despertares; consola USART0 para los mensajes
- SPL V2.2.x + OpenOCD compatible con GD32
Código completo
/* stop_rtc.c — GD32F103C8, SPL V2.2.x : Stop + reveil RTC chaque seconde. */
#include "gd32f10x.h"
static bool led_on = false;
void RTC_IRQHandler(void)
{
if (rtc_flag_get(RTC_FLAG_SECOND) == SET) {
rtc_flag_clear(RTC_FLAG_SECOND);
led_on = !led_on; /* la LED ne clignote qu'aux reveils */
gpio_bit_write(GPIOC, GPIO_PIN_13, led_on ? RESET : SET);
}
}
static void rtc_source_irc40k(void)
{
/* 1) source RTC = IRC40K interne (pas de quartz externe requis) */
rcu_osci_on(RCU_IRC40K);
rcu_osci_stab_wait(RCU_IRC40K);
rcu_rtc_clock_config(RCU_RTCSRC_IRC40K);
/* 2) horloge de la RTC et de la interface backup */
rcu_periph_clock_enable(RCU_PMU);
rcu_periph_clock_enable(RCU_BKPI);
pmu_backup_write_enable;
/* 3) RTC : prescaler 32768 -> 1 Hz, interruption « seconde » */
rtc_init;
rtc_interrupt_enable(RTC_INT_SECOND);
rtc_enable;
while (rtc_flag_get(RTC_FLAG_INITS) != SET) { } /* sync. registres */
nvic_priority_group_set(NVIC_PRIGROUP_PRE2_SUB2);
nvic_irq_enable(RTC_IRQn, 1, 0);
}
int main(void)
{
rcu_periph_clock_enable(RCU_GPIOC);
gpio_init(GPIOC, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_13);
rtc_source_irc40k;
while (1) {
/* Entree en Stop : WFI, le reveil se fait par l'IRQ RTC.
En Stop, le systeme repart sur IRC8M (8 MHz) au reveil :
reconfigurer le PLL 108 MHz si le code en a besoin. */
pmu_to_deepsleepmode(PMU_LDO_LOWPOWER, WFI_CMD, STOP_MODE_ENTRY);
/* ... ici, on revient a chaque seconde ... */
}
}
Verificación esperada
El LED PC13 pulsa una vez por segundo (en cada despertar RTC), y el microamperímetro cae fuertemente durante las fases de Stop en comparación con el modo run (en la escala de las centenas de µA frente a 34-45 mA en run a 108 MHz según la hoja de datos; el suelo de standby es de aproximadamente 5,6-5,8 µA con RTC activa). En modo de depuración SWD, la conexión puede caerse durante el Stop: es normal, recupere el control justo después de un despertar.
Errores frecuentes
- Ningún despertar: interrupción RTC activada pero se olvidó NVIC RTC_IRQn, o la bandera SECOND no se borró en el handler (el despertar entonces solo se produce una vez).
- El programa no se reanuda a la velocidad correcta: después de Stop, el reloj del sistema vuelve a IRC8M; todo código calibrado para 108 MHz (retrasos, UART) se desvía mientras el PLL no se reinicie.
- La RTC deja de contar tras el apagado: sin mantenimiento (VBAT o alimentación continua), la RTC vuelve a cero; el IRC40K interno es menos preciso que un LXTAL de 32,768 kHz.
- Confundir Stop y Standby: en Standby, la SRAM se pierde (reinicio completo al despertar, consumo mínimo ~5,6 µA); en Stop, la SRAM se conserva pero el consumo restante es mayor.
- Regulador y LED de la tarjeta: en una Blue Pill completa, el regulador y el LED consumen más que el MCU en Stop; sus medidas de µA estarán dominadas por la tarjeta, no por el chip.
- Despertar intempestivo: un pin flotante en una línea de wake-up puede despertar el núcleo; configure las entradas no utilizadas con un pull definido.
Otros tutoriales para esta placa
Ejemplos de código para esta placa
clignotante.inoArduinobouton-led.inoArduinorespiration.inoArduinopotentiometre.inoArduinopont-uart.inoArduinooled-i2c.inoArduino