STM32L151 RTC闹钟中断
Posted
技术标签:
【中文标题】STM32L151 RTC闹钟中断【英文标题】:STM32L151 RTC Alarm interrupt 【发布时间】:2017-01-13 16:58:33 【问题描述】: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 创建了项目。你对我有什么想法或建议吗?谢谢
【问题讨论】:
您可能需要在 NVIC 中启用中断。这可能被某些代码隐藏了,所以它可能已经完成了。查看NVIC中是否开启,如果开启,查看RTC中断开启是否正确(同时查看是否有挂起的中断)。 【参考方案1】:-
不要直接拨打
__HAL_RTC_ALARM_ENABLE_IT()
。它由HAL_RTC_SetAlarm_IT()
调用。
启用警报 B。为什么?因为有时,正如我所经历的那样,一个警报不起作用。您“有时”必须同时启用这两个警报。
对于屏蔽,您必须屏蔽所有位:
sAlarm.AlarmMask = RTC_ALARMMASK_DATEWEEKDAY|RTC_ALARMMASK_HOURS|RTC_ALARMMASK_MINUTES|RTC_ALARMMASK_SECONDS;
这样,您要求 ST 只使用秒。你也可以使用RTC_ALARMMASK_ALL
。
【讨论】:
【参考方案2】:如果某个字段被屏蔽,则在检查警报日期时不会进行比较。因此,当您屏蔽 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 应用说明中也描述了所有这些内容。
这是一个非常方便的解决方案,因为您不必在所有中断后重置警报。
【讨论】:
例如,如何每 5 秒完成一次? @KennetCeleste 恐怕你必须屏蔽除秒字段之外的所有内容,并在每次中断时重新配置警报。类似于另一个答案。什么会简化它从 HAL 转移到裸寄存器方法,因为 HAl 有巨大的开销。 @KennetCeleste 你想要一个 5 秒的闹钟吗? 1. 将时间屏蔽为每秒,然后使用变量为 0 和var++;
直到 var==5
。现在,调用你想要的任何函数。 (不要忘记将变量重置为 0)。 2.使用定时器。如果您将 RTC 时间设置为 5 秒,它将在 XX:XX:05
中断,而不是每 5 秒!【参考方案3】:
由于您设置了sAlarm.AlarmMask = RTC_ALARMMASK_SECONDS
,当时间的秒值与sAlarm.AlarmTime.Seconds
(在您的情况下为0
)匹配时,RTC 将生成中断。因此,如果您将代码保持原样,则每分钟都会有一次中断。
如果您希望每秒中断一次,则必须在中断处理程序中的下一秒再次设置警报。中断处理程序中的代码如下所示:
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
【讨论】:
这是一种合法的方法吗?或者这是一种解决方法? 您必须在HAL_RTC_GetTime
之后使用HAL_RTC_GetDate
。否则,它会被锁定。
@KennetCeleste 这是一种解决方法。 RTC 每秒自动生成一个警报。以上是关于STM32L151 RTC闹钟中断的主要内容,如果未能解决你的问题,请参考以下文章
STM32Cube STM32L053闹钟唤醒LL库和HAL库
Stm32L151RCxxx USART 挂起问题,同时基于中断的 TX/RX
STM32Cube STM32L053配置RTC WAKEUP中断唤醒