关于RTC时钟的HAL库配置我也是第一次,之前都是用库函数的写法,这里写下这篇博客来记录一下自己的学习过程。
首先点击左侧的Timers的RTC,勾选以下选项
进入时钟树配置
进入时间设置,这里我把时间设置为了2023年3月12日20点20分,但是我圈出来的地方一定要注意,125✖6000刚好是750Mhz,一秒发生一次中断
到此为止,我们的STM32Cubemx配置就算是结束了,直接点击生成代码,接下来就是写代码了。
这里有几点需要给大家强调一下,获取RTC时间或者日期时,必须先获取时间,再获取日期,顺序不能颠倒(会获取失败),而且时间和日期调用的时候不能单独调用,必须两个同时调用,否则出错,这是我实践得出的结果,即使我也不是太懂为啥。
RTC_TimeTypeDef sTime;
RTC_DateTypeDef sDate;
while (1)
{
HAL_RTC_GetTime(&hrtc, &sTime, RTC_FORMAT_BIN);
HAL_RTC_GetDate(&hrtc, &sDate, RTC_FORMAT_BIN);
sprintf((char *)LCD_dispaly,"%02d:%02d:%02d--%02d:%02d:%02d",sDate.Year,sDate.Month,sDate.Date,sTime.Hours,sTime.Minutes,sTime.Seconds);
LCD_DisplayStringLine(Line9,LCD_dispaly);
}
暂停功能,起始暂停功能我一开始是没有想起来的,后来才想到,把RTC给关了,那不就暂停了吗
__HAL_RCC_RTC_DISABLE();
恢复计时功能:
__HAL_RCC_RTC_ENABLE();
RTC 时钟其中一大功能就是闹钟中断,我们在SM32Cubemx中进行如下配置
将闹钟触发的时间设置为20:20:3,也就是初始时间的3秒后
然后我们使能中断
这里设置闹钟的话就需要对代码进行封装了
我们需要重新写一个GET_Time()函数,还有一个SET_Alarm()函数,同时要需要重新写一下RTC中断的回调函数
这里一开始我是不打算去写GET_Time()函数的,我决定直接用前面提到的两个函数不就可以了吗,结果报了两个警告,保险起见,我还是把这两个函数封装一下:
GET_Time():
void GET_Time(void)
{
HAL_RTC_GetTime(&hrtc, &sTime, RTC_FORMAT_BIN);
HAL_RTC_GetDate(&hrtc, &sDate, RTC_FORMAT_BIN);
}
SET_Alarm(),这个函数其实是我复制了MX_RTC_Init()里面的内容,然后更改一下就可以了,让每次中断的时候读取当前秒数,读取到的秒数再加上3就是下一次中断的触发时间。
void SET_Alarm(void)
{
RTC_AlarmTypeDef sAlarm = {0};
sAlarm.AlarmTime.Hours = 0x20;
sAlarm.AlarmTime.Minutes = 0x20;
sAlarm.AlarmTime.Seconds = sTime.Seconds+1;
sAlarm.AlarmTime.SubSeconds = 0x0;
sAlarm.AlarmMask = RTC_ALARMMASK_DATEWEEKDAY|RTC_ALARMMASK_HOURS
|RTC_ALARMMASK_MINUTES;
sAlarm.AlarmSubSecondMask = RTC_ALARMSUBSECONDMASK_ALL;
sAlarm.AlarmDateWeekDaySel = RTC_ALARMDATEWEEKDAYSEL_DATE;
sAlarm.AlarmDateWeekDay = 0x1;
sAlarm.Alarm = RTC_ALARM_A;
if (HAL_RTC_SetAlarm_IT(&hrtc, &sAlarm, RTC_FORMAT_BCD) != HAL_OK)
{
Error_Handler();
}
if(sAlarm.AlarmTime.Seconds==60)sAlarm.AlarmTime.Seconds=0;
HAL_RTC_SetAlarm_IT(&hrtc,&sAlarm,RTC_FORMAT_BIN);
if (HAL_RTC_SetAlarm_IT(&hrtc, &sAlarm, RTC_FORMAT_BCD) != HAL_OK)
{
Error_Handler();
}
}
之后,我们在RTC的回调函数中书写服务函数
void HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef *hrtc)
{
GET_Time();
SET_Alarm();
sprintf(string,"%02d:%02d:%02d\n",sTime.Hours,sTime.Minutes,sTime.Seconds);
HAL_UART_Transmit(&huart1,(unsigned char *)string,strlen(string),50);
}
每一秒向串口助手发送当前时间