Question
STM32F103CB and RTC interrupt
Posted on March 25, 2012 at 15:39
Hi all,
I am using the STM32F103CB microcontroller to develop an embedded application for wireless communications that needs to sleep and wake up periodically in order to save energy, as it runs from batteries. I have already developed the drivers to manage the GPIO, EXTI, SPI, etc. and right now I am trying to get the low power stuff to work using the STOP mode. What I do is enable the LSE clock (32kHz clock) to drive the RTC unit following the examples available. After that I put the microcontroller to STOP mode using the PWR_EnterSTOPMode instruction. Then, when the counter associated to the RTC unit overflows an interruption (RTC_IT_OW) should be fired. I have configured the NVIC_IRQChannel to handle the RTC_IRQn interrupt and have written the code to manage the interrupt. After the interruption is handled the code should keep running from where it stopped (the PWR_EnterSTOPMode instruction). I have set up an example as described and tried it using a logic analyzer using the GPIOs as debug ports. From what I see in the logic analyzer, the stop mode is entered and exited when the interrupt is produced but this happens only once, so that is weird. Could you please provide your insights? Thanks in advance. The code is as follows. Here's the code to init the RTC clock:void stm32f10x_rtc_init(void) {
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE); // Enable PWR/BKP
PWR_BackupAccessCmd(ENABLE); // Allow access to BKP Domain
BKP_DeInit(); // Reset Backup Domain
RCC_LSEConfig(RCC_LSE_ON); // Enable LSE
while ((RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET))
// Wait till LSE is ready
;
RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE); // Select LSE as RTC Clock Source
RCC_RTCCLKCmd(ENABLE); // Enable RTC Clock
RTC_WaitForSynchro(); // Wait for RTC registers synchronization
RTC_WaitForLastTask(); // Wait until last write operation on RTC registers has finished
RTC_ClearITPendingBit(RTC_IT_OW);
RTC_ITConfig(RTC_IT_OW, ENABLE); // Enables overflow interrupt
RTC_WaitForLastTask(); // Wait until last write operation on RTC registers has finished
RTC_SetPrescaler(1000); // Set RTC prescaler period to 10ms
RTC_WaitForLastTask(); // Wait until last write operation on RTC registers has finished
NVIC_InitTypeDef NVIC_InitStructure; // Configure the interrupt handler
NVIC_InitStructure.NVIC_IRQChannel = RTC_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
Here's the code to put the microcontroller to STOP mode:
void stm32f10x_rtc_stop(void) { // Puts the microcontroller to stop mode
stm32f10x_gpio_toggle(debug2_p, DISABLE);
PWR_EnterSTOPMode(PWR_Regulator_ON, PWR_STOPEntry_WFI); // stm32f10x_pwr.c
stm32f10x_gpio_toggle(debug2_p, ENABLE);
stm32f10x_rtc_sysclk_conf();
}
Here's the code to get the clocks back to work:
void stm32f10x_rtc_sysclk_conf(void) {
ErrorStatus HSEStartUpStatus;
/* Enable HSE */
RCC_HSEConfig(RCC_HSE_ON);
/* Wait till HSE is ready */
HSEStartUpStatus = RCC_WaitForHSEStartUp();
if (HSEStartUpStatus == SUCCESS) {
/* Enable PLL */
RCC_PLLCmd(ENABLE);
/* Wait till PLL is ready */
while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET) {
}
/* Select PLL as system clock source */
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
/* Wait till PLL is used as system clock source */
while (RCC_GetSYSCLKSource() != 0x08) {
}
}
}
Finally, here's the code to handle the interrupt:
volatile uint8_t rtc_status = 0;
void RTC_IRQHandler(void) { // @todo RTC interrupt handler
if (RTC_GetITStatus(RTC_IT_OW) != RESET) {
rtc_status = !rtc_status;
stm32f10x_gpio_toggle(debug1_p, rtc_status);
RTC_WaitForLastTask();
RTC_ClearITPendingBit(RTC_IT_OW);
RTC_WaitForLastTask();
}
}
Last but not least, here's the main code:
int main(void) {
stm32f10x_init(); // Inits GPIO, EXTI, etc.
stm32f10x_rtc_init(); // Inits the microcontroller RTC timer
while (1) {
stm32f10x_rtc_stop(); // Puts the microcontroller to stop mode
}
}
What am I overlooking? Any ideas? Thanks in advance!
Regards,
Pere
#stm32-rtc-stop