在STM32L452RE内部配置有RTC计时器,将它与OLED屏配合即可实现一个电子时钟。
实现图1所示效果的主程序为:
int main(void)
{
HAL_Init();
/* Configure the system clock to 80 MHz */
SystemClock_Config();
APP_OLED_Init();
OLED_Init();
OLED_Clear();
OLED_ShowString(8,0,"STM32L452RE",16);
OLED_ShowString(8,2,"OLED & RTC",16);
OLED_ShowCHinese(80,0,0);
OLED_ShowCHinese(96,0,1);
OLED_ShowCHinese(112,0,2);
/* Configure RTC prescaler and RTC data registers */
RtcHandle.Instance = RTC;
RtcHandle.Init.HourFormat = RTC_HOURFORMAT_24;
RtcHandle.Init.AsynchPrediv = RTC_ASYNCH_PREDIV;
RtcHandle.Init.SynchPrediv = RTC_SYNCH_PREDIV;
RtcHandle.Init.OutPut = RTC_OUTPUT_DISABLE;
RtcHandle.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH;
RtcHandle.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN;
if (HAL_RTC_Init(&RtcHandle) != HAL_OK)
{
/* Initialization Error */
Error_Handler();
}
/*##-2- Check if Data stored in BackUp register1: No Need to reconfigure RTC#*/
/* Read the Back Up Register 1 Data */
if (HAL_RTCEx_BKUPRead(&RtcHandle, RTC_BKP_DR1) != 0x32F2)
{
/* Configure RTC Calendar */
RTC_CalendarConfig();
}
/* Infinite loop */
while (1)
{
RTC_CalendarShow(aShowTime, aShowDate);
HAL_Delay(100);
}
}
图1 RTC电子时钟
实现RTC显示的函数为:
static void RTC_CalendarShow(uint8_t *showtime, uint8_t *showdate)
{
RTC_DateTypeDef sdatestructureget;
RTC_TimeTypeDef stimestructureget;
/* Get the RTC current Time */
HAL_RTC_GetTime(&RtcHandle, &stimestructureget, RTC_FORMAT_BIN);
/* Get the RTC current Date */
HAL_RTC_GetDate(&RtcHandle, &sdatestructureget, RTC_FORMAT_BIN);
/* Display time Format : hh:mm:ss */
sprintf((char *)showtime, "%2d:%2d:%2d", stimestructureget.Hours, stimestructureget.Minutes, stimestructureget.Seconds);
OLED_ShowString(26,6,showtime,16);
/* Display date Format : mm-dd-yy */
sprintf((char *)showdate, "%2d-%2d-%2d", 2000 + sdatestructureget.Year,sdatestructureget.Month, sdatestructureget.Date);
OLED_ShowString(10,4,showdate,16);
}
调用的字符串显示函数为:
void OLED_ShowString(u8 x,u8 y,u8 *chr,u8 Char_Size)
{
unsigned char j=0;
while (chr[j]!='\0')
{
OLED_ShowChar(x,y,chr[j],Char_Size);
x+=8;
if(x>120){x=0;y+=2;}
j++;
}
}
由于例程所设置的初始时间是2018年,故需要在函数 MX_RTC_Init()中进行修改,修改后的运行效果如图2所示。
图2 校时后的显示效果
有人可能会问RTC具备万年历的功能吗?
那我们就用实时来说话吧,首先它可以区分大小月,见图3和图4所示。
图3 11月末
图4 12月初
再看闰年处理,2020年是闰年,图5和图6就能说明问题。
图5 二月末
图6 闰年调整