实时时钟(RTC)模块是一种时间管理外设,主要用于记录和控制日期和时间。。RTC时钟的常用功能包括设置时间、设定闹钟、配置周期性中断以及启动或停止操作。通过使用Smart Configurator工具,我们可以轻松地对瑞萨微控制器进行RTC配置,从而实现高精度的时间和日期管理。本次测试中我将展示如何设置RTC时钟日历和产生一秒钟的中断,使得串口能够实时打印数据。
根据之前建立好的串口工程,我在此基础上进行RTC设置
1。首先打开 Smart Configurator工具,配置好串口
打开keil,在hal_entry.c文件 中添加如下串口重映射打印代码
fsp_err_t err = FSP_SUCCESS;
unsigned char send_buff[100];
volatile bool uart_send_complete_flag = false;
void user_uart9_callback (uart_callback_args_t * p_args)
{
switch (p_args->event)
{
case UART_EVENT_RX_CHAR:
{
/* °Ѵ®¿ڽӊյ½µĊý¾ݷ¢ˍ»؈¥ */
R_SCI_UART_Write(&g_uart9_ctrl, (uint8_t *)&(p_args->data), 1);
break;
}
case UART_EVENT_TX_COMPLETE:
{
uart_send_complete_flag = true;
break;
}
default:
break;
}
}
#if defined GNUC && !defined clang
int _write(int fd, char *pBuffer, int size); //·Àֹ±ҫ¾¯¸抩nt _write(int fd, char *pBuffer, int size)
{
(void)fd;
R_SCI_UART_Write(&g_uart9_ctrl, (uint8_t *)pBuffer, (uint32_t)size);
while(uart_send_complete_flag == false);
uart_send_complete_flag = false;
return size;
}
#else
int fputc(int ch, FILE *f)
{
(void)f;
R_SCI_UART_Write(&g_uart9_ctrl, (uint8_t *)&ch, 1);
while(uart_send_complete_flag == false);
uart_send_complete_flag = false;
return ch;
}
#endif
至此我们就完成了串口的打印功能
2。 配置RTC
点击Stacks->New Stack->Timers -> Realtime Clock(r_rtc)
进行如下配置
然后点击生成代码
3。打开KEIL
添加如下代码
/* rtc_time_t is an alias for the C Standard time.h struct 'tm' /
rtc_time_t set_time =
{
.tm_sec = 0, / 秒,范围从 0 到 59 /
.tm_min = 55, / 分,范围从 0 到 59 /
.tm_hour = 8, / 小时,范围从 0 到 23*/
.tm_mday = 18, /* 一月中的第几天,范围从 1 到 31*/
.tm_mon = 12, /* 月份,范围从 0 到 11*/
.tm_year = 124, /* 自 1900 起的年数,2021为121*/
.tm_wday = 3, /* 一周中的第几天,范围从 0 到 6*/
// .tm_yday=0, /* 一年中的第几天,范围从 0 到 365*/
// .tm_isdst=0; /* 夏令时*/
};
rtc_alarm_time_t set_alarm_time=
{
.time.tm_sec = 5,
.time.tm_sec = 5, /* 秒,范围从 0 到 59 /
.time.tm_min = 55, / 分,范围从 0 到 59 /
.time.tm_hour = 8, / 小时,范围从 0 到 23*/
.time.tm_mday = 18, /* 一月中的第几天,范围从 1 到 31*/
.time.tm_mon = 12, /* 月份,范围从 0 到 11*/
.time.tm_year = 124, /* 自 1900 起的年数,2021为121*/
.time.tm_wday = 3, /* 一周中的第几天,范围从 0 到 6*/
.sec_match = 1,
.min_match = 0,
.hour_match = 0,
.mday_match = 0,
.mon_match = 0,
.year_match = 0,
.dayofweek_match = 0,
};
volatile bool rtc_flag = 0;//RTC延时1s标志位
volatile bool rtc_alarm_flag = 0;//RTC闹钟
/* Callback function */
void rtc_callback(rtc_callback_args_t p_args)
{
/ TODO: add your own code here */
if(p_args->event == RTC_EVENT_PERIODIC_IRQ)
rtc_flag=1;
else if(p_args->event == RTC_EVENT_ALARM_IRQ)
rtc_alarm_flag=1;
}
至此已经完成了RTC配置及核心代码处理
3。在hal_entry函数中添加如下代码
void hal_entry (void)
{
#if BSP_TZ_SECURE_BUILD
R_BSP_NonSecureEnter();
#endif
hal_systick_init();
err = R_SCI_UART_Open(&g_uart9_ctrl, &g_uart9_cfg);
assert(FSP_SUCCESS == err);
err = R_RTC_Open(&g_rtc0_ctrl, &g_rtc0_cfg);
assert(FSP_SUCCESS == err);
R_RTC_CalendarTimeSet(&g_rtc0_ctrl, &set_time);
R_RTC_PeriodicIrqRateSet(&g_rtc0_ctrl, RTC_PERIODIC_IRQ_SELECT_1_SECOND);
R_RTC_CalendarAlarmSet(&g_rtc0_ctrl, &set_alarm_time);
uint8_t rtc_second= 0;
uint8_t rtc_minute =0;
uint8_t rtc_hour =0;
uint8_t rtc_day =0;
uint8_t rtc_month =0;
uint16_t rtc_year =0;
uint8_t rtc_week =0;
rtc_time_t get_time;
printf("/************************串口测试********************************/\n");
while(1)
{
if(rtc_flag)
{
R_RTC_CalendarTimeGet(&g_rtc0_ctrl, &get_time);
rtc_flag=0;
rtc_second=get_time.tm_sec;
rtc_minute=get_time.tm_min;
rtc_hour=get_time.tm_hour;
rtc_day=get_time.tm_mday;
rtc_month=get_time.tm_mon;
rtc_year=get_time.tm_year;
rtc_week=get_time.tm_wday;
// printf(" %d y %d m %d d %d h %d m %d s %d w\n",rtc_year+1900,rtc_month,rtc_day,rtc_hour,rtc_minute,rtc_second,rtc_week);
printf("当前时间为%d年%d月%d日%d时%d分%d秒%dw\n",rtc_year+1900,rtc_month,rtc_day,rtc_hour,rtc_minute,rtc_second,rtc_week);
}
if(rtc_alarm_flag)
{
rtc_alarm_flag=0;
printf("/Alarm Clock********/\n");
}
}
}
编译代码,烧录到板子上
可以从串口助手上看到真实的年月日时分秒日期了,RTC功能测试完成OK.