RA MCU众测宝典 | 串口之【RA2L1】开发板开箱及串口输出实现
RA MCU众测宝典 | PWM之【RA2L1】呼吸灯
ADC/DAC之【RA2L1】DAC电压输出及ADC电压采集实验
本次实验内容是调用RTC实时时钟,实现日历、串口设定时间的功能。
01
硬件部分:RTC
RTC时钟模块是一个时间外设,主要用于日期时间的存储和控制,有别于一般MCU中的 Timer,RTC时钟有两种计时模式,日期模式和计时模式,RTC常见的操作包括设置时间、设置定时闹铃、配置周期性中断以及启动或停止操作。
02
软件部分
1
配置RTC
选择Stacks选项卡:
序号 | 操作 |
1 | 点击界面下方标签栏中的Stacks标签,进入堆栈配置页面。 |
2 | 在HAL/Common Stacks区域,点击New Stack按钮。 |
3 | 在弹出菜单中,选择Timers选项。 |
4 | 在Timers子菜单中,选择Realtime Clock (r_rtc)。 |

点击可查看大图
序号 | 操作 |
1 | 在Settings设置区域的Module g_rtc0 Realtime Clock (r_rtc)部分,找到Clock Source,将其设置为Sub-Clock。 |
2 | 在Settings设置区域的Module g_rtc0 Realtime Clock (r_rtc)部分,设置Callback为rtc_callback。 |
3 | 在Settings设置区域的Module g_rtc0 Realtime Clock (r_rtc)部分,分别设置Alarm Interrupt Priority、Period Interrupt Priority、Carry Interrupt Priority为Priority 2。 |

点击可查看大图
配置完成后,生成项目代码。
2
编写代码
将先前的项目模板复制一份,重命名为03_RTC。
2.1 新建rtc.h
新建文件rtc.h,加入以下代码:
左右滑动查看完整内容
#ifndef RTC_H_#define RTC_H_#include"hal_data.h"externrtc_time_t set_time;externvolatilebool rtc_flag;#endif
2.2 新建rtc.c
这段代码定义一个set_time结构体,用于在主函数中配置,同时实现了rtc_callback回调函数,用于每1秒中断一次使用:
左右滑动查看完整内容
#include"hal_data.h"#include"rtc.h"
rtc_time_t set_time = { .tm_sec = 59, /* 秒,范围从 0 到 59 */ .tm_min = 59, /* 分,范围从 0 到 59 */ .tm_hour = 23, /* 小时,范围从 0 到 23*/ .tm_mday = 28, /* 一月中的第几天,范围从 1 到 31*/ .tm_mon = 1, /* 月份,范围从 0 到 11(0代表1月,11代表12月)*/ .tm_year = 125, /* 自 1900 起的年数,2021 为 121*/};
volatilebool rtc_flag = false; // RTC 延时 1s 标志位
voidrtc_callback(rtc_callback_args_t *p_args){ if (p_args->event == RTC_EVENT_PERIODIC_IRQ) rtc_flag = true;}
2.3 修改hal_entry.c
在文件开头加入代码:
左右滑动查看完整内容
#include"rtc.h"
rtc_time_t get_time;
在hal_entry函数中加入代码,主要功能是初始化了rtc、配置时间以及解析串口接收到的设定时间的信息:
左右滑动查看完整内容
g_rtc0.p_api->open(&g_rtc0_ctrl, &g_rtc0_cfg); g_rtc0.p_api->calendarTimeSet(&g_rtc0_ctrl, &set_time); g_rtc0.p_api->periodicIrqRateSet(&g_rtc0_ctrl, RTC_PERIODIC_IRQ_SELECT_1_SECOND); while (1) { if (rtc_flag) { g_rtc0.p_api->calendarTimeGet(&g_rtc0_ctrl, &get_time); // 获取 RTC 计数时间 rtc_flag = 0; printf("%d年%d月%d日 %d:%d:%d\n", get_time.tm_year + 1900, get_time.tm_mon +1, get_time.tm_mday, get_time.tm_hour, get_time.tm_min, get_time.tm_sec); } if (uart_rx_complete_flag) { char * time; uart_rx_complete_flag = 0; // 解析设置时间的命令 e.g: time:20250126080910 // warning: 未添加错误纠正算法,请输入正确的时间,否则工作异常! if(strncmp(rx_data, "time:", 5) == 0){ time = rx_data+5; set_time.tm_year = ((time[0]-'0')*1000)+((time[1]-'0')*100)+ ((time[2]-'0')*10)+(time[3]-'0')-1900; set_time.tm_mon = ((time[4]-'0')*10)+(time[5]-'0') - 1; set_time.tm_mday = ((time[6]-'0')*10)+(time[7]-'0'); set_time.tm_hour = ((time[8]-'0')*10)+(time[9]-'0'); set_time.tm_min = ((time[10]-'0')*10)+(time[11]-'0'); set_time.tm_sec = ((time[12]-'0')*10)+(time[13]-'0'); g_rtc0.p_api->calendarTimeSet(&g_rtc0_ctrl, &set_time); } } }
2.4 修改debug_bsp_uart.c
该文件的内容如下:
左右滑动查看完整内容
#include"debug_bsp_uart.h"/* 发送完成标志 */volatileint uart_send_complete_flag = 0;volatileint uart_rx_complete_flag = 0;
char rx_data[1024];volatileuint16_t cnt;uint8_t stat = 0;/* 调试串口 UART9 初始化 */voidDebug_UART9_Init(void){ fsp_err_t err = FSP_SUCCESS;
err = R_SCI_UART_Open(&g_uart9_ctrl, &g_uart9_cfg); assert(FSP_SUCCESS == err);}
/* 串口中断回调 */voiddebug_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); rx_data[cnt++] = (char)p_args->data; if (stat == 0 && p_args->data == '\r') { stat = 1; } elseif (stat == 1 && p_args->data == '\n') { // 接收完一行 uart_rx_complete_flag = 1; cnt = 0; } else { stat = 0; }
break; } case UART_EVENT_TX_COMPLETE: { uart_send_complete_flag = 1; break; }
default: break; }}
/* 重定向 printf 输出 */#if defined __GNUC__ && !defined __clang__int _write(int fd, char *pBuffer, int size); // 防止编译警告int _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 == 0) ; uart_send_complete_flag = 0;
return size;}#elseintfputc(int ch, FILE *f){ (void)f; R_SCI_UART_Write(&g_uart9_ctrl, (uint8_t *)&ch, 1); while (uart_send_complete_flag == 0) ; uart_send_complete_flag = 0;
return ch;}#endif
2.5 修改debug_bsp_uart.h
该文件的内容如下:
左右滑动查看完整内容
#ifndef DEBUG_BSP_UART_H_#define DEBUG_BSP_UART_H_#include"hal_data.h"#include"stdio.h"voidDebug_UART9_Init(void);externvolatileint uart_rx_complete_flag;externchar rx_data[1024];#endif
03
下载测试
把编译好的程序下载到开发板并复位,打开串口助手,在发送框输入:

点击可查看大图
注
如果串口助手没有自动添加\r\n,则上面的结尾需要手动加上\r\n,否则程序无法识别该命令。
程序中未作纠错,请勿输入错误的时间,否则日历将出错。
04
工程附件
工程附件-RTC
https://bbs.elecfans.com/jishu_2474886_1_1.html
全部0条评论
快来发表一下你的评论吧 !