2015-11-19 02:22 PM
I'm working on some code to set the RTC alarm, and I've gone through all the resources I can find on how to set this up correctly, but it's just not working. If you could take a look and see if I've missed anything, or something is in the wrong order, I would really appreciate it.
I've just hard coded some dummy values for simplicity. &sharpdefine USE_HSI RTC_TimeTypeDef current_time_base;// a typedef struct
RTC_DateTypeDef current_date_base;// a typedef struct
RTC_AlarmTypeDef alarm_time_base;// a typedef struct
RTC_Format_TypeDef time_format = RTC_Format_BCD;// a typedef enum
RTC_InitTypeDef initialization_constants_base;// a typedef struct
void
main(void
) { RTC_DeInit(); enableInterrupts(); initialization_constants_base.RTC_HourFormat =0
; initialization_constants_base.RTC_AsynchPrediv =124
;// for HSI
initialization_constants_base.RTC_SynchPrediv =1999
;// for HSI
if
(RTC_Init(&initialization_constants_base) == SUCCESS); CLK_RTCClockConfig(CLK_RTCCLKSource_HSI, CLK_RTCCLKDiv_64);// for HSI
current_time_base.RTC_H12 = RTC_H12_AM;// 24 hour format
current_time_base.RTC_Hours =0x17
;// 5pm
current_time_base.RTC_Minutes =0x43
;// 43 minutes
current_time_base.RTC_Seconds =0x28
;// 28 seconds
if
(RTC_SetTime(time_format, ¤t_time_base) == SUCCESS); current_date_base.RTC_WeekDay = RTC_Weekday_Monday;// I don't care about the day of the week
current_date_base.RTC_Month =0x12
;// December
current_date_base.RTC_Date =0x17
;// 17th
current_date_base.RTC_Year =0x15
;//2015
if
(RTC_SetDate(time_format, ¤t_date_base) == SUCCESS); alarm_time_base.RTC_AlarmMask = RTC_AlarmMask_None;// Alarm goes off if the entire exact time matches
alarm_time_base.RTC_AlarmDateWeekDaySel = RTC_AlarmDateWeekDaySel_Date;// I don't care about the day of the week
alarm_time_base.RTC_AlarmDateWeekDay =0x00
;// wait 0 days
alarm_time_base.RTC_AlarmTime.RTC_H12 = RTC_H12_AM;// 24 hour format
alarm_time_base.RTC_AlarmTime.RTC_Hours =0x00
;// wait 0 hours
alarm_time_base.RTC_AlarmTime.RTC_Minutes =0x00
;// wait 0 minutes
alarm_time_base.RTC_AlarmTime.RTC_Seconds =0x12
;// wait 12 seconds
RTC_ITConfig(RTC_IT_ALRA, ENABLE); RTC_OutputConfig(RTC_Output_Alarm, RTC_OutputPolarity_High); RTC->CR2 |= RTC_CR2_ALRAIE; RTC_SetAlarm(time_format, &alarm_time_base);if
(RTC_AlarmCmd(ENABLE) == SUCCESS); }And I have this piece of code in my stm8l15x_it.c file:
INTERRUPT_HANDLER(RTC_IRQHandler,4
) { nop(); RTC_ClearITPendingBit(RTC_IT_ALRA); }And the interrupt never happens.
#rtc #rtc-stm8l #problem #stm8l #stm82015-11-30 02:34 PM
Okay, an update. I was searching ST's site and found newer library files to use, and some RTC example code (STM8L15x-16x-05x-AL31-L_StdPeriph_Lib from
http://www.st.com/web/catalog/tools/FM147/CL1794/SC1807/SS1754/PF257956
)! Yay! So I created a new project and a new workspace, and using the RTC_Calendar example code, I re-wrote my main:#define USE_LSE // the 768kHz external crystal
//#define USE_HSI // the internal clock for debugging
// ... function declarations
RTC_InitTypeDef RTC_InitStr;
RTC_TimeTypeDef RTC_TimeStr;
RTC_DateTypeDef RTC_DateStr;
RTC_AlarmTypeDef RTC_AlarmStr;
/**
* @brief Main program.
* @param None
* @retval None
*/
void
main(
void
)
{
nop();
/* Select HSI as system clock source */
#ifdef USE_HSI
CLK_SYSCLKSourceConfig(CLK_SYSCLKSource_HSI);
CLK_SYSCLKDivConfig(CLK_SYSCLKDiv_16);
CLK_RTCClockConfig(CLK_RTCCLKSource_HSI, CLK_RTCCLKDiv_64);
#else
/* Enable LSE */
CLK_LSEConfig(CLK_LSE_ON);
/* Wait for LSE clock to be ready */
while
(CLK_GetFlagStatus(CLK_FLAG_LSERDY) == RESET);
/* wait for 1 second for the LSE Stabilisation */
LSE_StabTime();
/* Select LSE (768 KHz) as RTC clock source */
CLK_RTCClockConfig(CLK_RTCCLKSource_LSE, CLK_RTCCLKDiv_1);
#endif
CLK_PeripheralClockConfig(CLK_Peripheral_RTC, ENABLE);
/* Calendar Configuration */
Calendar_Init();
//... some GPIO initialization
enableInterrupts();
while
(1)
{
nop();
GPIO_ToggleBits(PORTD_GPIO_PORT, GPIO_Pin_2);
}
}
/**
* @brief Calendar Configuration.
* @param None
* @retval None
*/
void
Calendar_Init(
void
)
{
RTC_InitStr.RTC_HourFormat = RTC_HourFormat_24;
#ifdef USE_HSI
RTC_InitStr.RTC_AsynchPrediv = 0x7C;
// for HSI
RTC_InitStr.RTC_SynchPrediv = 0x07CF;
// for HSI
#else
RTC_InitStr.RTC_AsynchPrediv = 0x7F;
// for LSE
RTC_InitStr.RTC_SynchPrediv = 0x00FF;
// for LSE
#endif
RTC_Init(&RTC_InitStr);
RTC_DateStructInit(&RTC_DateStr);
RTC_DateStr.RTC_WeekDay = RTC_Weekday_Monday;
RTC_DateStr.RTC_Date = 0x25;
RTC_DateStr.RTC_Month = 0x11;
RTC_DateStr.RTC_Year = 0x15;
RTC_SetDate(RTC_Format_BCD, &RTC_DateStr);
RTC_TimeStructInit(&RTC_TimeStr);
RTC_TimeStr.RTC_Hours = 0x15;
RTC_TimeStr.RTC_Minutes = 0x32;
RTC_TimeStr.RTC_Seconds = 0x44;
RTC_SetTime(RTC_Format_BCD, &RTC_TimeStr);
RTC_AlarmStructInit(&RTC_AlarmStr);
RTC_AlarmStr.RTC_AlarmTime.RTC_Hours = 0x00;
RTC_AlarmStr.RTC_AlarmTime.RTC_Minutes = 0x00;
RTC_AlarmStr.RTC_AlarmTime.RTC_Seconds = 0x12;
RTC_AlarmStr.RTC_AlarmMask = RTC_AlarmMask_DateWeekDay;
// might want to change...
RTC_SetAlarm(RTC_Format_BCD, &RTC_AlarmStr);
RTC_ITConfig(RTC_IT_ALRA, ENABLE);
RTC_AlarmCmd(ENABLE);
}
So this is supposed to initialize the current date and time, set the RTC alarm for 12 seconds, and then toggle an LED pin (port D, pin 2) until the alarm goes off.
and then in my stm8l15x_it.c,
INTERRUPT_HANDLER(RTC_CSSLSE_IRQHandler,4)
{
// The RTC alarm has gone off (timer duration reached)
GPIO_SetBits(PORTD_GPIO_PORT, GPIO_Pin_2);
// clear the interrput
RTC_ClearITPendingBit(RTC_IT_ALRA);
while
(1)
{
nop();
//wait here with the LED on.
}
}
When the alarm goes off, the LED is supposed to stay constant on, and then sit in the ISRdoing nothing forever.
The alarm still never activates. What is going on? I followed the RTC example code, and double checked that I didn't miss anything. Has anyone had an RTC problem like this? Any help would be so appreciated. Thanks.
2015-12-10 09:35 AM
Ok, another update. I contacted ST technical support, and I was setting up the RTC wrong. If I want the day, hour, minute, and second to match exactly (I do) then I should set no mask for the RTC alarm, and the RTC alarm time is not the duration I want the alarm to be, but the absolute time I want the alarm to go off. So if I set:
RTC_Init(&RTC_InitStr);
RTC_DateStructInit(&RTC_DateStr);
RTC_DateStr.RTC_Month = 0x12;
// December
RTC_DateStr.RTC_Date = 0x09;
// 9th
RTC_DateStr.RTC_Year = 0x15;
// 2015
RTC_SetDate(RTC_Format_BCD, &RTC_DateStr);
RTC_TimeStructInit(&RTC_TimeStr);
RTC_TimeStr.RTC_Hours = 0x17;
// 5pm
RTC_TimeStr.RTC_Minutes = 0x00;
// 0 minutes
RTC_TimeStr.RTC_Seconds = 0x00;
// 0 seconds
RTC_SetTime(RTC_Format_BCD, &RTC_TimeStr);
RTC_AlarmStructInit(&RTC_AlarmStr);
RTC_AlarmStr.RTC_AlarmDateWeekDaySel = RTC_AlarmDateWeekDaySel_Date;
// the RTC_AlarmDateWeekDay is the date 0 to 31, not the weekday 1 to 7
RTC_AlarmStr.RTC_AlarmDateWeekDay = 0x10;
// the 10th
RTC_AlarmStr.RTC_AlarmTime.RTC_Hours = 0x08;
// 8am
RTC_AlarmStr.RTC_AlarmTime.RTC_Minutes = 0x30;
// 30 minutes
RTC_AlarmStr.RTC_AlarmTime.RTC_Seconds = 0x00;
// 0 seconds
RTC_AlarmStr.RTC_AlarmMask = RTC_AlarmMask_None;
// the entire exact time needs to match (month and year aren't handled by the system)
RTC_SetAlarm(RTC_Format_BCD, &RTC_AlarmStr);
RTC_ITConfig(RTC_IT_ALRA, ENABLE);
RTC_AlarmCmd(ENABLE);
The RTC alarm successfully went off this morning at 8:30am (actually about 8:35am, but I'm using the HSI clock so I don't expect it to be super accurate). From 5pm yesterday to 8:30am today is 15 hours, 30 minutes or 930 minutes. So the alarm went off in 935 minutes or +0.54%, well within the HSI tolerance of +/- 1% @ Vdd = 3.0V @ 25C, or the + 3% / -4.5% @ 1.65V <= Vdd <= 3.6V @ -40C <= Ta <= 125C.
tl;dr - The RTC alarm time is an absolute time, not a duration. If you put in an alarm time of 3 hours, that means ''3am'' not ''3 hours from now''.