2025-04-03 2:32 AM - last edited on 2025-04-03 2:37 AM by Andrew Neil
Moved from the Feedback Forum.
The Feeedback Forum is not for product questions.
Hi,
I'm using Keil platform for programme my STM32 L073RZT6 and I am making it in bare metal. I would like to wake up the STM from any sleep mode using and interruption from the RTC Wake Up. I am using the following code to configure the RTC:
/********* Configuración del RTC *********/
// Desbloqueo de la protección de escritura del reloj
SET_BIT(PWR->CR, PWR_CR_DBP);
SET_BIT(PWR->CR, PWR_CR_CWUF);
// Reinicio del RTC
SET_BIT(RCC -> CSR, RCC_CSR_RTCRST);
for(int a = 0; a <1000 ; a++){}
CLEAR_BIT(RCC -> CSR, RCC_CSR_RTCRST);
// Establecimiento del reloj para el RTC
MODIFY_REG(RCC -> CSR, RCC_CSR_RTCSEL_Msk, RCC_CSR_RTCSEL_LSI);
for(int a = 0; a <1000 ; a++){}
// Habilita el RTC
SET_BIT(RCC -> CSR, RCC_CSR_RTCEN);
// Desbloqueo del RTC mediante las claves de seguridad
WRITE_REG(RTC -> WPR, 0xCA);
WRITE_REG(RTC -> WPR, 0x53);
// Establece el modo de iniciación
if (READ_BIT(RTC->ISR, RTC_ISR_INITF) == 0U)
{
// Activa el bit de inicio
SET_BIT(RTC->ISR, RTC_ISR_INIT);
// Espera a entrar en modo inicio
while (READ_BIT(RTC->ISR, RTC_ISR_INITF) == 0U);
}
// Establece el escalado general del RTC
WRITE_REG(RTC->PRER, (36 << 16) | (999));//(255 << RTC_PRER_PREDIV_A_Pos) | (270 << RTC_PRER_PREDIV_S_Pos));
// Establece el registro de bypass para la lectura
SET_BIT(RTC->CR, RTC_CR_BYPSHAD);
CLEAR_BIT(RTC->CR, RTC_CR_FMT);
CLEAR_BIT(RTC->CR, RTC_CR_REFCKON);
// Desactiva el modo de inicio y se inician los contadores de cuenta
CLEAR_BIT(RTC->ISR, RTC_ISR_INIT);
while (READ_BIT(RTC->ISR, RTC_ISR_INITF) != 0U){};
// Comprobar que la bandera del WakeUp esté bajada
if ((RTC->CR & RTC_CR_WUTE) != 0U){
while ((RTC->ISR & RTC_ISR_WUTWF)!=0U);
}
// Deshabilitar el Wake-Up Timer antes de configurarlo
RTC->CR &= ~RTC_CR_WUTE;
// Limpia la bandera de interrupción.
RTC->ISR &= ~RTC_ISR_WUTF;
while ((RTC->ISR & RTC_ISR_WUTWF)==0U);
// Seleccionar la fuente del Wake-Up Timer
RTC->CR &= ~RTC_CR_WUCKSEL_Msk; // 1Hz
RTC->CR |= 4U << RTC_CR_WUCKSEL_Pos;
// Configurar el contador para 5 segundos
RTC->WUTR = 20;
// Habilitar la interrupción del Wake-Up Timer
RTC->CR |= RTC_CR_WUTIE;
// Habilitar el Wake-Up Timer
RTC->CR |= RTC_CR_WUTE;
EXTI->IMR |= EXTI_IMR_IM20;
EXTI->RTSR |= EXTI_RTSR_TR20;
EXTI->PR = EXTI_PR_PR20;
NVIC_EnableIRQ(RTC_IRQn);
// Bloquear el RTC
RTC->WPR = 0xFF;
With this code I use the LSI as CLK for the RTC. I use the 1Hz clk for the wakeUp. RTC is working and I can get the time from it, but the WUTR register is not dicrement his count. Someone could help me to find what is the error with the code. Thanks you for the help.
Solved! Go to Solution.
2025-04-10 1:47 AM
Hello again @Jose_Manuel_Bravo,
>> and i was triying to use it in run Mode
This is not supported!
Could you follow this article and tell me if it works on your side: How to configure the RTC to wake up the STM32 peri... - STMicroelectronics Community
To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
2025-04-07 2:10 AM
Hello @Jose_Manuel_Bravo,
The RTC_WUTR contains the wakeup auto-reload value bits (WUT[15:0]) not a downcounter, could you read that the WUTF flag is set when the wakeup timer is enabled (WUTE set to 1)?
To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
2025-04-07 3:22 AM
I just read the value when the wake up timer is enable, and it is set to 0. I read that wake up timer only works in stop Mode an standby Mode, and i was triying to use it in run Mode. I belived that I could change to use the Alarm A, but it does'n work too. I add my fuction code of the RTC configuration.
void InitRTC(void){
/********* Configuración del RTC *********/
// Desbloqueo de la protección de escritura del reloj
SET_BIT(PWR->CR, PWR_CR_DBP);
SET_BIT(PWR->CR, PWR_CR_CWUF);
// Reinicio del RTC
SET_BIT(RCC -> CSR, RCC_CSR_RTCRST);
for(int a = 0; a <1000 ; a++){}
CLEAR_BIT(RCC -> CSR, RCC_CSR_RTCRST);
// Establecimiento del reloj para el RTC
MODIFY_REG(RCC -> CSR, RCC_CSR_RTCSEL_Msk, RCC_CSR_RTCSEL_LSI);
for(int a = 0; a <1000 ; a++){}
// Habilita el RTC
SET_BIT(RCC -> CSR, RCC_CSR_RTCEN);
// Desbloqueo del RTC mediante las claves de seguridad
WRITE_REG(RTC -> WPR, 0xCA);
WRITE_REG(RTC -> WPR, 0x53);
// Establece el modo de iniciación
if (READ_BIT(RTC->ISR, RTC_ISR_INITF) == 0U)
{
// Activa el bit de inicio
SET_BIT(RTC->ISR, RTC_ISR_INIT);
// Espera a entrar en modo inicio
while (READ_BIT(RTC->ISR, RTC_ISR_INITF) == 0U);
}
// Establece el escalado general del RTC
WRITE_REG(RTC->PRER, (36 << 16) | (999));//(255 << RTC_PRER_PREDIV_A_Pos) | (270 << RTC_PRER_PREDIV_S_Pos));
// Establece el registro de bypass para la lectura
SET_BIT(RTC->CR, RTC_CR_BYPSHAD);
CLEAR_BIT(RTC->CR, RTC_CR_FMT);
CLEAR_BIT(RTC->CR, RTC_CR_REFCKON);
// Comprobar que la bandera del WakeUp esté bajada
if ((RTC->CR & RTC_CR_WUTE) != 0U){
while ((RTC->ISR & RTC_ISR_WUTWF)!=0U);
}
// Desactiva el modo de inicio y se inician los contadores de cuenta
CLEAR_BIT(RTC->ISR, RTC_ISR_INIT);
while (READ_BIT(RTC->ISR, RTC_ISR_INITF) != 0U){};
/** Sistema de wake up en stop mode (no en uso) **/
// Deshabilitar el Wake-Up Timer antes de configurarlo
RTC->CR &= ~RTC_CR_WUTE;
// Limpia la bandera de interrupción.
RTC->ISR &= ~RTC_ISR_WUTF;
while ((RTC->ISR & RTC_ISR_WUTWF)==0U);
// Seleccionar la fuente del Wake-Up Timer (LSI/32 -> ~1.156 kHz)
RTC->CR &= ~RTC_CR_WUCKSEL_Msk; // LSI/16
RTC->CR |= 4U << RTC_CR_WUCKSEL_Pos;
// Configurar el contador para 5 segundos
// Con LSI = ~37 kHz: (37,000 / 32) ˜ 1,156 Hz -> 5s = 5780 ticks
RTC->WUTR = 0x0000FFFF;
for(int a = 0; a <1000 ; a++){}
RTC->WUTR = 20;
// Habilitar la interrupción del Wake-Up Timer
RTC->CR |= RTC_CR_WUTIE;
// Habilitar el Wake-Up Timer
RTC->CR |= RTC_CR_WUTE;
EXTI->IMR |= EXTI_IMR_IM20;
EXTI->RTSR |= EXTI_RTSR_TR20;
EXTI->PR = EXTI_PR_PR20;
for(int a = 0; a <10 ; a++){}
TxUartCadena(uartHandler_aux , "********** Valores Antes de configuracion **********\n");
TxUartCadena(uartHandler_aux , "Valor registro RTC->ALRMAR:\n");
TxUartRegister(uartHandler_aux , RTC->ALRMAR);
TxUartByte(uartHandler_aux , '\n');
TxUartCadena(uartHandler_aux , "Valor registro RTC->CR:\n");
TxUartRegister(uartHandler_aux , RTC->CR);
TxUartByte(uartHandler_aux , '\n');
TxUartCadena(uartHandler_aux , "Valor registro RTC->ISR:\n");
TxUartRegister(uartHandler_aux , RTC->ISR);
TxUartByte(uartHandler_aux , '\n');
TxUartCadena(uartHandler_aux , "Valor RTC->TR:\n");
TxUartRegister(uartHandler_aux , RTC->TR);
TxUartByte(uartHandler_aux , '\n');
// Deshabilitar la alarma A
RTC->CR &= ~RTC_CR_ALRAE;
RTC->CR &= ~RTC_CR_ALRAIE;
RTC->ISR &= ~RTC_ISR_ALRAF;
while ((RTC->ISR & RTC_ISR_ALRAWF) == 0U){}; // Esperar a que esté listo
TxUartCadena(uartHandler_aux , "********** Valores Despues de desactivar ALARMA **********\n");
TxUartCadena(uartHandler_aux , "Valor registro RTC->ALRMAR:\n");
TxUartRegister(uartHandler_aux , RTC->ALRMAR);
TxUartByte(uartHandler_aux , '\n');
TxUartCadena(uartHandler_aux , "Valor registro RTC->CR:\n");
TxUartRegister(uartHandler_aux , RTC->CR);
TxUartByte(uartHandler_aux , '\n');
TxUartCadena(uartHandler_aux , "Valor registro RTC->ISR:\n");
TxUartRegister(uartHandler_aux , RTC->ISR);
TxUartByte(uartHandler_aux , '\n');
TxUartCadena(uartHandler_aux , "Valor RTC->TR:\n");
TxUartRegister(uartHandler_aux , RTC->TR);
TxUartByte(uartHandler_aux , '\n');
RTC->ALRMAR = 0;
RTC->ALRMAR |= RTC_ALRMAR_MSK4;
RTC->ALRMAR |= RTC_ALRMAR_MSK3;
RTC->ALRMAR |= RTC_ALRMAR_MSK2;
RTC->ALRMAR |= (0 << RTC_ALRMAR_ST_Pos);
RTC->ALRMAR |= (5);
RTC->ALRMASSR = 0;
TxUartCadena(uartHandler_aux , "********** Valores Tras configuracion **********\n");
TxUartCadena(uartHandler_aux , "Valor registro RTC->ALRMAR:\n");
TxUartRegister(uartHandler_aux , RTC->ALRMAR);
TxUartByte(uartHandler_aux , '\n');
TxUartCadena(uartHandler_aux , "Valor registro RTC->CR:\n");
TxUartRegister(uartHandler_aux , RTC->CR);
TxUartByte(uartHandler_aux , '\n');
TxUartCadena(uartHandler_aux , "Valor registro RTC->ISR:\n");
TxUartRegister(uartHandler_aux , RTC->ISR);
TxUartByte(uartHandler_aux , '\n');
TxUartCadena(uartHandler_aux , "Valor RTC->TR:\n");
TxUartRegister(uartHandler_aux , RTC->TR);
TxUartByte(uartHandler_aux , '\n');
// Habilitar la alarma A
RTC->CR |= RTC_CR_ALRAE;
// Habilitar la interrupción de la alarma A
RTC->CR |= RTC_CR_ALRAIE;
//while ((RTC->ISR & RTC_ISR_ALRAWF) != 0U){};
EXTI->PR = EXTI_PR_PR17; // Limpiar la bandera de interrupción de la línea 17
EXTI->IMR |= EXTI_IMR_IM17; // Habilitar la línea 17 para la alarma A
EXTI->RTSR |= EXTI_RTSR_TR17; // Configurar para el flanco de subida
NVIC_EnableIRQ(RTC_IRQn);
NVIC_SetPriority(RTC_IRQn, 0);
TxUartCadena(uartHandler_aux , "********** Valores Finales **********\n");
TxUartCadena(uartHandler_aux , "Valor registro RTC->ALRMAR:\n");
TxUartRegister(uartHandler_aux , RTC->ALRMAR);
TxUartByte(uartHandler_aux , '\n');
TxUartCadena(uartHandler_aux , "Valor registro RTC->CR:\n");
TxUartRegister(uartHandler_aux , RTC->CR);
TxUartByte(uartHandler_aux , '\n');
TxUartCadena(uartHandler_aux , "Valor registro RTC->ISR:\n");
TxUartRegister(uartHandler_aux , RTC->ISR);
TxUartByte(uartHandler_aux , '\n');
TxUartCadena(uartHandler_aux , "Valor RTC->TR:\n");
TxUartRegister(uartHandler_aux , RTC->TR);
TxUartByte(uartHandler_aux , '\n');
// Bloquear el RTC
RTC->WPR = 0xFF;
}
Thanks for the help.
2025-04-10 1:47 AM
Hello again @Jose_Manuel_Bravo,
>> and i was triying to use it in run Mode
This is not supported!
Could you follow this article and tell me if it works on your side: How to configure the RTC to wake up the STM32 peri... - STMicroelectronics Community
To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.