2013-10-15 11:44 PM
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 #rtc2013-10-16 03:13 AM
Why can't you use RTC wakeup IRQ, it seems more flexible than the RTC second IRQ in F1 series.
2013-10-16 02:25 PM
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
2013-10-16 06:13 PM
// 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
}
2013-10-17 08:52 AM
Many thanks for the code Clive !