cancel
Showing results for 
Search instead for 
Did you mean: 

[STM32L152] 1 Hz interrupts using an external 32.768 oscillator and RTC clock

quentin239955_stm1_st
Associate II
Posted on October 16, 2013 at 08:44

Hey everyone,

I'm currently trying to generate 1 Hz interrupts using the LSE oscillator of my STM32L discovery board. I have already configured my RTC clock succesfully. My problem is as follow: I know that the STM32F serie offers RTC overflow interrupts to generate an interrupt every second, upon checking, it doesn't seem that the STM32L series has the same features (I've only seen RTC wake up and alarm interrupts). That being said I was wondering if there was a way around, i.e. can I use the same 32.768 oscillator I use for RTC as clock source for one of the Timers (TIMx) ? My project involves measuring a voltage every second and saving it in an array along with the time at which it was measured. Ideally, I'd like to use the same clock source to trigger the measure and get the time at which it was performed. I know I could set up a TIMx timer to generate interrupts every second using the internal oscillator. However I'm concerned that the difference in accuracy and drift that would occur between the two separate clock sources will cause trouble. I will be taking measures over long periods (typically weeks or months), and if the internal timer runs slightly slower than the RTC, there is a high risk I am gonna get two measures in one second, or one second will be skipped periodically ...

Thanks in advance for any help you can provide

Cheers,

Quin 

#timer #wakeup #stm32 #rtc
4 REPLIES 4
zzdz2
Associate II
Posted on October 16, 2013 at 12:13

Why can't you use RTC wakeup IRQ, it seems more flexible than the RTC second IRQ in F1 series.

quentin239955_stm1_st
Associate II
Posted on October 16, 2013 at 23:25

Hi Knik,

First off thanks for your answer, I followed your advice and tried setting up the wake up interrupt, unfortunately nothing happens ... I've been scratching my head over this for several hours now, here is my code:


int
RTC_CLOCK_INIT(){


RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE); 

PWR_RTCAccessCmd(ENABLE);

//Enable LSE oscillator (768 Hz)

RCC_LSEConfig(RCC_LSE_ON); 

RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);

RCC_RTCCLKCmd(ENABLE);

// Wait for LSE to be ready

while
(RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET);

return
0;

}


int
RTC_NVID_INIT()

{

NVIC_InitTypeDef NVIC_InitStructure;

//Generate 1 Hz interrupts

RTC_WakeUpClockConfig(RTC_WakeUpClock_CK_SPRE_16bits);

RTC_SetWakeUpCounter(0x0);

//Enable wake up interrupts

RTC_ITConfig(RTC_IT_WUT, ENABLE);

//Enable wake up counter

RTC_WakeUpCmd(ENABLE);

while
(RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET) ;

//Init NVIC

NVIC_InitStructure.NVIC_IRQChannel = RTC_WKUP_IRQn;

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

NVIC_Init(&NVIC_InitStructure);

return
0;

}


int
RTC_WKUP_IRQHandler()

{

if
(RTC_GetITStatus(RTC_IT_WUT) != RESET)

{

//Do something


}

RTC_ClearITPendingBit(RTC_IT_WUT);

}


int
main() {

RTC_CLOCK_INIT();

RTC_NVID_INIT();

while
(1) {


}


return
0;

}

Also regarding the wake up timer, is it possible to use it without putting or exiting the MCU in/from sleep mode ? Thanks in advance for any help you can provide !! Quin
Posted on October 17, 2013 at 03:13

// STM32L15x RTC 1 Hz Demo - STM32L-Discovery - sourcer32@gmail.com
#include ''discover_board.h''
/**************************************************************************************/
void RTC_WKUP_IRQHandler(void)
{
if (RTC_GetITStatus(RTC_IT_WUT) != RESET)
{
RTC_ClearITPendingBit(RTC_IT_WUT);
EXTI_ClearITPendingBit(EXTI_Line20);
/* Toggle on BLUE LED */
GPIO_TOGGLE(LD_GPIO_PORT, LD_BLUE_GPIO_PIN);
}
}
/**************************************************************************************/
void RTC_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
EXTI_InitTypeDef EXTI_InitStructure;
RTC_InitTypeDef RTC_InitStructure;
RTC_TimeTypeDef RTC_TimeStruct;
/* Enable the PWR clock */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
/* Allow access to RTC */
PWR_RTCAccessCmd(ENABLE);
/* Reset RTC Domain */
RCC_RTCResetCmd(ENABLE);
RCC_RTCResetCmd(DISABLE);
/* Enable the LSE OSC */
RCC_LSEConfig(RCC_LSE_ON);
/* Wait till LSE is ready */
while(RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET) {}
/* Select the RTC Clock Source */
RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);
/* Configure the RTC data register and RTC prescaler */
RTC_InitStructure.RTC_AsynchPrediv = 0x7F;
RTC_InitStructure.RTC_SynchPrediv = 0xFF;
RTC_InitStructure.RTC_HourFormat = RTC_HourFormat_24;
RTC_Init(&RTC_InitStructure);
/* Set the time to 00h 00mn 00s AM */
RTC_TimeStruct.RTC_H12 = RTC_H12_AM;
RTC_TimeStruct.RTC_Hours = 0x00;
RTC_TimeStruct.RTC_Minutes = 0x00;
RTC_TimeStruct.RTC_Seconds = 0x00;
RTC_SetTime(RTC_Format_BIN, &RTC_TimeStruct);
/* Enable the RTC Clock */
RCC_RTCCLKCmd(ENABLE);
/* Wait for RTC APB registers synchronisation */
RTC_WaitForSynchro();
/* EXTI configuration *******************************************************/
EXTI_ClearITPendingBit(EXTI_Line20);
EXTI_InitStructure.EXTI_Line = EXTI_Line20;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
/* Enable the RTC Wakeup Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = RTC_WKUP_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
/* Configure the RTC WakeUp Clock source: CK_SPRE (1Hz) */
RTC_WakeUpClockConfig(RTC_WakeUpClock_CK_SPRE_16bits);
RTC_SetWakeUpCounter(0x0);
/* Enable the RTC Wakeup Interrupt */
RTC_ITConfig(RTC_IT_WUT, ENABLE);
/* Enable Wakeup Counter */
RTC_WakeUpCmd(ENABLE);
}
/**************************************************************************************/
void GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/* GPIO clock enable */
RCC_AHBPeriphClockCmd(LD_GPIO_PORT_CLK, ENABLE);
GPIO_InitStructure.GPIO_Pin = LD_BLUE_GPIO_PIN | LD_GREEN_GPIO_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(LD_GPIO_PORT, &GPIO_InitStructure);
}
/**************************************************************************************/
int main(void)
{
/* Initialize LEDs mounted on STM32L-Discovery board --------------------------*/
GPIO_Configuration();
/* RTC Configuration -------------------------------------------------------*/
RTC_Configuration();
GPIO_HIGH(LD_GPIO_PORT, LD_GREEN_GPIO_PIN);
while(1); // Don't want to exit
}

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
quentin239955_stm1_st
Associate II
Posted on October 17, 2013 at 17:52

Many thanks for the code Clive !