Question
STM32F050G4 RTC Alarm Problems
Posted on October 31, 2013 at 09:23
Hi All, a couple of questions about the RTC Alarm. I have got the RTC Alarm working (using LSI), and raising an interrupt (RTC_IRQHandler()) successfully, but I'm stuck on the following:-
1) I would like an alarm once a second, so I can put the core in stop mode, and have it wake up once a second. The reference manual implies that if I set the ALRMASSR MASKSS to zero, and set all the ALRMAR MSK bits, then I should get an interrupt once a second, but I don't. I used RTC->ALRMAR = 0x80808080; RTC->ALRMASSR = 0x00000000; 2) Whilst I can set RTC->ALRMAR in the first place, I cannot modify it within RTC_IRQHandler() for the next alarm. I'm disabling WPR. I have attached my test code below. You'll notice the debug vars ben1, ben2, ben3 - if I pause a few seconds after the first alarm interrupt, ben2 (ALRMAR) is still 0x80808 You'll notice from commented code that I also tried the library functions for setting the alarm, and even tried RTC_EnterInitMode(), same problem. Any suggestions?#include ''stm32f0xx.h''
#include ''stm32f0xx_gpio.h''
#include ''stm32f0xx_rcc.h''
#include ''stm32f0xx_pwr.h''
#include ''stm32f0xx_rtc.h''
#include ''stm32f0xx_exti.h''
#include ''stm32f0xx_misc.h''
#define PORT_LED GPIOB
#define PIN_LED_G GPIO_Pin_6
#define PIN_LED_R GPIO_Pin_7
#define LED_G_ON GPIOB->BSRR=PIN_LED_G
#define LED_G_OFF GPIOB->BRR=PIN_LED_G
#define LED_G_TOGGLE GPIOB->ODR ^= PIN_LED_G
#define LED_R_ON GPIOB->BSRR=PIN_LED_R
#define LED_R_OFF GPIOB->BRR=PIN_LED_R
#define LED_R_TOGGLE GPIOB->ODR ^= PIN_LED_R
uint32_t ben1, ben2, ben3;
int
main(
void
)
{
GPIO_InitTypeDef GPIO_InitStructure;
RTC_InitTypeDef RTC_InitStructure;
//RTC_TimeTypeDef RTC_TimeStructure;
//RTC_TimeTypeDef bentemp_rtc;
//ErrorStatus benerrorstatus;
//uint32_t benui32;
// Outputs Port B
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);
GPIO_InitStructure.GPIO_Pin = PIN_LED_G | PIN_LED_R;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
// Init RTC Clock
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
// Enable the PWR clock
PWR_BackupAccessCmd(ENABLE);
// Enable access to the Backup domain registers (PWR->CR |= PWR_CR_DBP;)
RCC_LSICmd(ENABLE);
// Enable the LSI OSC
while
(RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET);
// and wait until ready
RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI);
// Set RTC clock source to LSI (RCC->BDCR |= RCC_RTCCLKSource_LSI;) must set PWR_CR_DBP first
RCC_RTCCLKCmd(ENABLE);
// Enable RTC Clock (RCC->BDCR |= RCC_BDCR_RTCEN;)
RTC_WaitForSynchro();
// Wait for RTC APB registers synchronisation
// Set RTC prescaler register RTC_PRER
RTC_InitStructure.RTC_AsynchPrediv = 99;
RTC_InitStructure.RTC_SynchPrediv = 399;
/* (40KHz / 100) - 1 = 399*/
RTC_InitStructure.RTC_HourFormat = RTC_HourFormat_24;
RTC_Init(&RTC_InitStructure);
// Init RTC time register
// ben note the RTC_SetTime() function doesn't appear to work...
RTC->WPR = 0xCA;
// Disable the write protection for RTC registers
RTC->WPR = 0x53;
// ditto
RTC_EnterInitMode();
// Enter initialisation mode
RTC->TR = (uint32_t)0x00000000;
// Set the RTC_TR register
RTC->ISR &= ~RTC_ISR_INIT;
// Exit initialisation mode
RTC->WPR = 0xFF;
// Enable the write protection for RTC registers
// Init EXTI line 17
EXTI->RTSR |= EXTI_IMR_MR17;
// set rising edge bit
EXTI->IMR |= EXTI_IMR_MR17;
// set interrupt mask bit
// Enable the RTC Interrupt
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = RTC_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
// Set RTC alarm
RTC->WPR = 0xCA;
RTC->WPR = 0x53;
RTC->ALRMAR = 0x80808005;
// MSK4=1(ignore day/date), MSK3=1(ignore hours), MSK2=1(ignore minutes), MSK1=0 ST=0 SU=5 secs
//RTC->ALRMAR = 0x80808080; // MSK4=1(ignore day/date), MSK3=1(ignore hours), MSK2=1(ignore minutes), MSK1=1(ignore seconds)
//RTC->ALRMASSR = 0x00000000; // MASKSS=0 so the alarm is set when the seconds unit is incremented
RTC->CR |= RTC_CR_ALRAIE;
// enable alarm interrupt ben was RTC_ITConfig(RTC_IT_ALRA, ENABLE);
RTC->CR |= RTC_CR_ALRAE;
// enable alarm
RTC->WPR = 0xFF;
// and finally clear any pending interrupts
RTC_ClearITPendingBit(RTC_IT_ALRA);
EXTI_ClearITPendingBit(EXTI_Line17);
while
(1)
{
ben1 = RTC->TR;
ben2 = RTC->ALRMAR;
}
}
void
RTC_IRQHandler(
void
)
{
LED_G_TOGGLE;
/*
// set next alarm
RTC_WaitForSynchro(); //ben only if we read TR -
//uint32_t fred = RTC->ALRMAR & 0x0000007F;
uint32_t fred = RTC->TR & 0x0000007F;
fred += 5;
if (fred > 59)
fred = 0;
ben3 = fred;
*/
RTC->WPR = 0xCA;
RTC->WPR = 0x53;
//RTC->ALRMAR = 0x80808000 | fred; // MSK4=1(ignore day/date), MSK3=1(ignore hours), MSK2=1(ignore minutes), MSK1=0 ST/U = fred secs
RTC->ALRMAR = 0x80808009;
// MSK4=1(ignore day/date), MSK3=1(ignore hours), MSK2=1(ignore minutes), MSK1=0 ST/U = fred secs
RTC->WPR = 0xFF;
/* RTC_WriteProtectionCmd(DISABLE);
RTC_EnterInitMode();
//RTC_SetAlarm(RTC_Format_BIN, RTC_Alarm_A, &alarm);
RTC->ALRMAR = 0x80808009; // MSK4=1(ignore day/date), MSK3=1(ignore hours), MSK2=1(ignore minutes), MSK1=0 ST/U = fred secs
RTC_WriteProtectionCmd(ENABLE);
RTC_ExitInitMode();
*/
RTC_ClearITPendingBit(RTC_IT_ALRA);
EXTI_ClearITPendingBit(EXTI_Line17);
}
#stm32 #wakeup #rtc #timer