我遇到STM32L151的RTC报警中断问题。我希望我的程序每秒都进入RTC警报中断,但它不起作用。 我的主要功能:
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_IWDG_Init();
MX_RTC_Init();
MX_SPI1_Init();
MX_USART1_UART_Init();
__HAL_RTC_ALARM_ENABLE_IT(&hrtc, RTC_IT_ALRA);
while (1)
{
}
}
功能配置RTC:MX_RTC_Init():
void MX_RTC_Init(void)
{
RTC_TimeTypeDef sTime;
RTC_DateTypeDef sDate;
RTC_AlarmTypeDef sAlarm;
hrtc.Instance = RTC;
hrtc.Init.HourFormat = RTC_HOURFORMAT_24;
hrtc.Init.AsynchPrediv = 127;
hrtc.Init.SynchPrediv = 255;
hrtc.Init.OutPut = RTC_OUTPUT_DISABLE;
hrtc.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH;
hrtc.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN;
HAL_RTC_Init(&hrtc);
sTime.Hours = 0x14;
sTime.Minutes = 0;
sTime.Seconds = 0;
sTime.TimeFormat = RTC_HOURFORMAT12_AM;
sTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;
sTime.StoreOperation = RTC_STOREOPERATION_RESET;
HAL_RTC_SetTime(&hrtc, &sTime, FORMAT_BCD);
sDate.WeekDay = RTC_WEEKDAY_WEDNESDAY;
sDate.Month = RTC_MONTH_AUGUST;
sDate.Date = 0x24;
sDate.Year = 0x16;
HAL_RTC_SetDate(&hrtc, &sDate, FORMAT_BCD);
/**Enable the Alarm A
*/
sAlarm.AlarmTime.Hours = 0;
sAlarm.AlarmTime.Minutes = 0;
sAlarm.AlarmTime.Seconds = 0;
sAlarm.AlarmTime.TimeFormat = RTC_HOURFORMAT12_AM;
sAlarm.AlarmTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;
sAlarm.AlarmTime.StoreOperation = RTC_STOREOPERATION_RESET;
sAlarm.AlarmMask = RTC_ALARMMASK_SECONDS;
sAlarm.AlarmDateWeekDaySel = RTC_ALARMDATEWEEKDAYSEL_DATE;
sAlarm.AlarmDateWeekDay = 1;
sAlarm.Alarm = RTC_ALARM_A;
HAL_RTC_SetAlarm_IT(&hrtc, &sAlarm, FORMAT_BCD);
}
我使用CubeMX创建了项目。你对我有什么想法或建议吗?谢谢
答案 0 :(得分:4)
如果屏蔽某个字段,则在检查警报日期时不会比较该字段。因此,当您屏蔽SECONDS时,只会比较DAY,HOUR和MINUTE字段。 使用RTC实现1秒中断的正确方法是使用所有警报掩码,因为这样就不会比较任何字段,并且当RTC递增SECOND字段时,将生成警报中断。
sAlarm.AlarmMask = RTC_ALARMMASK_ALL;
所有这些都由ST在他们的Using the hardware real-time clock (RTC) in STM32 F0, F2, F3, F4 and L1 series of MCUs申请说明中描述。
这是一个非常方便的解决方案,因为您不必在所有中断后重置警报。
答案 1 :(得分:1)
当您设置sAlarm.AlarmMask = RTC_ALARMMASK_SECONDS
时,如果时间的秒值与sAlarm.AlarmTime.Seconds
匹配,则RTC将生成中断,在您的情况下为0
。因此,如果您保留代码,则每分钟都会有一个中断。
如果您希望每秒进行一次中断,则必须在中断处理程序中使用下一秒再次设置警报。中断处理程序中的代码如下所示:
void HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef *hrtc)
{
RTC_TimeTypeDef sTime;
HAL_RTC_GetTime(&hrtc, &sTime, RTC_FORMAT_BIN);
uint8_t next_second = sTime.Seconds++;
if (next_second > 59) next_second = 0;
RTC_AlarmTypeDef sAlarm;
sAlarm.AlarmTime.Hours = 0;
sAlarm.AlarmTime.Minutes = 0;
sAlarm.AlarmTime.Seconds = RTC_ByteToBcd2(next_second);
sAlarm.AlarmTime.TimeFormat = RTC_HOURFORMAT12_AM;
sAlarm.AlarmTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;
sAlarm.AlarmTime.StoreOperation = RTC_STOREOPERATION_RESET;
sAlarm.AlarmMask = RTC_ALARMMASK_SECONDS;
sAlarm.AlarmDateWeekDaySel = RTC_ALARMDATEWEEKDAYSEL_DATE;
sAlarm.AlarmDateWeekDay = 1;
sAlarm.Alarm = RTC_ALARM_A;
HAL_RTC_SetAlarm_IT(&hrtc, &sAlarm, FORMAT_BCD);
}
为此,您必须确保已正确设置RTC时钟(内部或外部32K)。
或者你可以使用RTC的唤醒功能,我觉得更合适。
或者在主循环中,您可以使用HAL_GetTick
检查自上次处理以来已经过了1秒,如下所示:
static uint32_t last_second = 0;
void main(void)
{
uint32_t current_second = HAL_GetTick();
if (current_second - last_second > 1000)
{
last_second = current_second;
//1 second has elapsed, do something
}
}