瑞萨RA MCU众测宝典 | 串口之【RA-Eco-RA2L1】RTC日历及串口设置时间

描述

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)。

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。

RTC

点击可查看大图


 

配置完成后,生成项目代码。
 

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


 

下载测试


 

把编译好的程序下载到开发板并复位,打开串口助手,在发送框输入:

RTC

点击可查看大图


 

如果串口助手没有自动添加\r\n,则上面的结尾需要手动加上\r\n,否则程序无法识别该命令。

程序中未作纠错,请勿输入错误的时间,否则日历将出错。


 

04


 

工程附件


 


 

工程附件-RTC

https://bbs.elecfans.com/jishu_2474886_1_1.html

 

 

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分