2014-09-10 01:43 PM
Hello guys, I am having some problems with the following code:
void RTC_Configuration(void)
{ RTC_InitTypeDef RTC_InitStructure; RTC_TimeTypeDef RTC_TimeStructure; RTC_DateTypeDef RTC_DateStructure; NVIC_InitTypeDef NVIC_InitStructure; EXTI_InitTypeDef EXTI_InitStructure; /* Enable the PWR clock */ RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE); /* Allow access to RTC */ PWR_BackupAccessCmd(ENABLE); // Reset the backup domain, clear RTC RCC_BackupResetCmd(ENABLE); RCC_BackupResetCmd(DISABLE); if (RCC_GetFlagStatus(RCC_FLAG_HSERDY) == RESET) /* HSE Already running? */ { /* Enable the LSI OSC */ RCC_HSEConfig(RCC_HSE_ON); /* Wait till LSI is ready */ while(RCC_GetFlagStatus(RCC_FLAG_HSERDY) == RESET); } /* Select the RTC Clock Source */ RCC_RTCCLKConfig(RCC_RTCCLKSource_HSE_Div8); /* Enable the RTC Clock */ RCC_RTCCLKCmd(ENABLE); /* Wait for RTC APB registers synchronisation */ RTC_WaitForSynchro(); /* Espero la suncronizacion de los registros APB RTC */ RTC_InitStructure.RTC_AsynchPrediv = 123 - 1; /* Condiguracion del calendario para HSE/8 = 1 MHz */ RTC_InitStructure.RTC_SynchPrediv = 8146 - 1; RTC_InitStructure.RTC_HourFormat = RTC_HourFormat_24; RTC_Init(&RTC_InitStructure); RTC_DateStructure.RTC_Year = 14; /* Seteo la fecha al 1/1/14 */ RTC_DateStructure.RTC_Month = RTC_Month_January; RTC_DateStructure.RTC_Date = 0x01; RTC_DateStructure.RTC_WeekDay = RTC_Weekday_Wednesday; RTC_SetDate(RTC_Format_BCD, &RTC_DateStructure); RTC_TimeStructure.RTC_H12 = RTC_H12_AM; RTC_TimeStructure.RTC_Hours = 0; RTC_TimeStructure.RTC_Minutes = 0; RTC_TimeStructure.RTC_Seconds = 0; RTC_SetTime(RTC_Format_BCD, &RTC_TimeStructure); /* Configuro las interrupciones */ EXTI_ClearITPendingBit(EXTI_Line22); EXTI_InitStructure.EXTI_Line = EXTI_Line22; EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling; EXTI_InitStructure.EXTI_LineCmd = ENABLE; EXTI_Init(&EXTI_InitStructure); NVIC_InitStructure.NVIC_IRQChannel = RTC_WKUP_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 5; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); RTC_WakeUpCmd(DISABLE); //RTC_WriteProtectionCmd(DISABLE);
/* Configure the RTC WakeUp Clock source: CK_SPRE (1Hz) */ RTC_WakeUpClockConfig(RTC_WakeUpClock_CK_SPRE_16bits); RTC_SetWakeUpCounter(1); /* Enable the RTC Wakeup Interrupt */ RTC_ITConfig(RTC_IT_WUT, ENABLE); RTC_ITConfig(RTC_IT_TS, DISABLE); RTC_ITConfig(RTC_IT_ALRA, DISABLE); RTC_ITConfig(RTC_IT_ALRB, DISABLE); RTC_ITConfig(RTC_IT_TAMP, DISABLE); RTC_ITConfig(RTC_IT_TAMP1, DISABLE); RTC_ClearFlag(RTC_FLAG_WUTF); RTC_ClearITPendingBit(RTC_IT_WUT); EXTI_ClearITPendingBit(EXTI_Line22); //RTC_AlarmCmd(RTC_Alarm_A, DISABLE);
//RTC_AlarmCmd(RTC_Alarm_B, DISABLE);
//RTC_TimeStampCmd(RTC_TimeStampEdge_Rising, DISABLE);
//RTC_TimeStampCmd(RTC_TimeStampEdge_Falling, DISABLE);
//RTC_TamperFilterConfig(RTC_TamperFilter_Disable);
//RTC_TamperCmd(RTC_Tamper_1, DISABLE);
//RTC_TamperPullUpCmd(DISABLE);
//RTC_BypassShadowCmd(DISABLE);
//RTC_CoarseCalibCmd(DISABLE);
//RTC_WriteProtectionCmd(ENABLE);
/* Enable Wakeup Counter */ RTC_WakeUpCmd(ENABLE); } void RTC_WKUP_IRQHandler(void){ if(RTC_GetITStatus(RTC_IT_WUT) != RESET){ Aux++; RTC_WriteProtectionCmd(DISABLE); EXTI_ClearITPendingBit(EXTI_Line22); RTC_ClearITPendingBit(RTC_IT_WUT); RTC_ClearFlag(RTC_FLAG_WUTF); RTC_ClearFlag(RTC_FLAG_RECALPF); RTC_ClearFlag(RTC_FLAG_TAMP1F); RTC_ClearFlag(RTC_FLAG_TSOVF); RTC_ClearFlag(RTC_FLAG_TSF); RTC_ClearFlag(RTC_FLAG_WUTF); RTC_ClearFlag(RTC_FLAG_ALRBF); RTC_ClearFlag(RTC_FLAG_ALRAF); RTC_ClearFlag(RTC_FLAG_WUTF); RTC_ClearFlag(RTC_FLAG_INITF); RTC_ClearFlag(RTC_FLAG_RSF); RTC_ClearFlag(RTC_FLAG_SHPF); RTC_ClearFlag(RTC_FLAG_WUTWF); RTC_ClearFlag(RTC_FLAG_ALRBWF); RTC_ClearFlag(RTC_FLAG_ALRAWF); RTC_WriteProtectionCmd(ENABLE); } } The idea is to have an interrupt every second but when the first interrupt is fired then constantly enters in the interrupt, some times because of the RTC_IT_WUTF and some others because of others flags. I have been trying a lot of things but without success. I don't know what I am doing wrong. Can you help me? Thanks a lot. Best regards, Bruno #discovery #stm32f4 #wait-for-you--clive1-!-!-!2014-09-10 04:22 PM
Which STM32 part, an F2 or F4 at a guess? Never mind saw the tags...
I don't have time right now to dig through this, but I think you need to explicitly test/clear the EXTI source, rather than make it dependent on other sources. If you fail to clear it, the interrupt will keep reentering. You should also be able to test/set/clear multiple status bits in a single operation. Interrupt flags can assert separately from whether they are enabled. The enabling just means the flag is gated through to the interrupt controller.2014-09-10 05:15 PM
Dear clive1,
As always thank you for your answer. I am sorry to tell you I did not understand what do you meant with ''You should also be able to test/set/clear multiple status bits in a single operation. Interrupt flags can assert separately from whether they are enabled. The enabling just means the flag is gated through to the interrupt controller.''I do not why but I cannot understand it. As you probably noticed, my english is not good at all.Regarding to the EXTI source, I have cleared the pending bit in the interrupt when a valid RTC_IT_WUT interrupt arrives, which seems to be the first one fired but then there are some invalid fires until another WUF and so. I do not know if I am clear enough.Al the RTC_ClearFlag() in the ISR are the result of my tests. I tried with a single if sentence for each flag and the result was that the undesired fires of the ISR was not because of any of the IT sources (WUT, TS, ALRA, ALRB, TAMP, TAMP1). All the flags were in RESET state but some of the RTC_Flags were in SET state. What I remember is that RTC_FLAG_WUTF, RTC_FLAG_RSF, RTC_FLAG_ALRAWF, RTC_FLAG_ALRBWF and probably another one were set.Could you give me some clue of what I should review?Thank you again!Best regards,BrunoPD: I am using an STM32F407VGT62014-09-10 07:59 PM
RTC_ITConfig(RTC_IT_WUT, ENABLE); // Enable singular source
RTC_ITConfig(RTC_IT_TS | RTC_IT_ALRA | RTC_IT_ALRB, DISABLE); // Disable multiple sources
RTC_ClearFlag(RTC_FLAG_TAMP1F | RTC_FLAG_TSOVF | RTC_FLAG_TSF |
RTC_FLAG_WUTF | RTC_FLAG_ALRBF | RTC_FLAG_ALRAF | RTC_FLAG_RSF); // Clear multiple flags
if (EXTI_GetITStatus(EXTI_Line22) != RESET)
{
EXTI_ClearITPendingBit(EXTI_Line22);
// ...
}
2014-09-11 04:48 AM
Great, thank you so much.
Now it almost work. The interrupt is triggered correctly a couple of times and then it does not trigger again but well, I will figure it out. The single ClearFlag() calls was because I was testing, lol. ** EDIT ** Let me share the final configuration that worked:void RTC_Configuration(void)
{
RTC_InitTypeDef RTC_InitStructure;
RTC_TimeTypeDef RTC_TimeStructure;
RTC_DateTypeDef RTC_DateStructure;
NVIC_InitTypeDef NVIC_InitStructure;
EXTI_InitTypeDef EXTI_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE); /* Habilito el PWR clock */
PWR_BackupAccessCmd(ENABLE); /* Permito Acceso al RTC */
RCC_BackupResetCmd(ENABLE);
RCC_BackupResetCmd(DISABLE);
if (RCC_GetFlagStatus(RCC_FLAG_HSERDY) == RESET){ /* HSE activado? */
RCC_HSEConfig(RCC_HSE_ON); /* Sino activo HSE */
while(RCC_GetFlagStatus(RCC_FLAG_HSERDY) == RESET);
}
RCC_RTCCLKConfig(RCC_RTCCLKSource_HSE_Div8); /* 8015674 Hz / 8 = 1001959,25 Hz*/
RCC_RTCCLKCmd(ENABLE); /* Habilito el clock */
RTC_WaitForSynchro(); /* Espero la suncronizacion de los registros APB RTC */
RTC_InitStructure.RTC_AsynchPrediv = 123 - 1; /* 1001959 / 123 = 8146 / */
RTC_InitStructure.RTC_SynchPrediv = 8146 - 1;
RTC_InitStructure.RTC_HourFormat = RTC_HourFormat_24;
RTC_Init(&RTC_InitStructure);
RTC_DateStructure.RTC_Year = 14; /* Seteo la fecha al 1/1/14 */
RTC_DateStructure.RTC_Month = RTC_Month_January;
RTC_DateStructure.RTC_Date = 0x01;
RTC_DateStructure.RTC_WeekDay = RTC_Weekday_Wednesday;
RTC_SetDate(RTC_Format_BCD, &RTC_DateStructure);
RTC_TimeStructure.RTC_H12 = RTC_H12_AM;
RTC_TimeStructure.RTC_Hours = 0;
RTC_TimeStructure.RTC_Minutes = 0;
RTC_TimeStructure.RTC_Seconds = 0;
RTC_SetTime(RTC_Format_BCD, &RTC_TimeStructure);
/* Configuro las interrupciones */
EXTI_ClearITPendingBit(EXTI_Line22);
EXTI_InitStructure.EXTI_Line = EXTI_Line22;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = RTC_WKUP_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 5;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
RTC_WakeUpCmd(DISABLE);
RTC_WriteProtectionCmd(DISABLE);
RTC_WakeUpClockConfig(RTC_WakeUpClock_CK_SPRE_16bits);
RTC_SetWakeUpCounter(0x01); /* Interrupcion cada 1 segundo */
RTC_ITConfig(RTC_IT_WUT, ENABLE); /* Enable the RTC Wakeup Interrupt */
RTC_ITConfig(RTC_IT_TAMP | RTC_IT_TAMP1 | RTC_IT_TS |
RTC_IT_ALRA | RTC_IT_ALRB, DISABLE); /* Disable multiple sources */
RTC_ClearFlag(RTC_FLAG_WUTF);
RTC_ClearITPendingBit(RTC_IT_WUT);
EXTI_ClearITPendingBit(EXTI_Line22);
RTC_WriteProtectionCmd(ENABLE);
RTC_WakeUpCmd(ENABLE); /* Habilito contador Wake UP */
}
void RTC_WKUP_IRQHandler(void){
if (EXTI_GetITStatus(EXTI_Line22) != RESET){
Aux++;
RTC_WriteProtectionCmd(DISABLE);
EXTI_ClearITPendingBit(EXTI_Line22);
RTC_ClearITPendingBit(RTC_IT_WUT);
RTC_ClearFlag(RTC_FLAG_WUTF);
RTC_ClearFlag(RTC_FLAG_TAMP1F | RTC_FLAG_TSOVF | RTC_FLAG_TSF |
RTC_FLAG_WUTF | RTC_FLAG_ALRBF | RTC_FLAG_ALRAF | RTC_FLAG_RSF); /* Clear multiple flags */
RTC_WriteProtectionCmd(ENABLE);
}
}