瑞萨单片机论坛
直播中

jf_43382582

未满1年用户 116经验值
擅长:可编程逻辑 嵌入式技术 EMC/EMI设计 存储技术
私信 关注

【RA4L1-SENSOR】+ RA4L1-SENSOR开发板之使用RTC显示实时时间并在段码屏LCD上显示时间年月日时分秒完美切换

断码屏显示时间

e5e16d93d6dc376bd5cb82840985125.jpg

很高兴收到瑞萨电子发放的RA4L1开发板,这个板子上带了一个非常好的段码屏LCD,搭配这个屏可以做成万年历,显示时分秒实时时间。比如现在时间是16:20:23,含义就是16时20分23秒。刚好可以显示在段码屏上,6个数码管。如果要显示年月日的话,可以做成两屏,通过按键进行切换,一个屏显示年月日,下一个屏显示时分秒!!!

上面就是基本原理,只要理解了,就可以实现这样的功能。

这里核心功能就是需要使用到RTC模块。RA4L1板载RTC模块,可以获取实时时钟。

好的,话不多说,直接上干货!!

1。打开瑞萨的smart配置软件
image.png

按照上面的配置设置好RTC参数

2。设置串口
image.png

image.png

上面是串口参数

3。添加核心代码

#include "hal_data.h"

#include "usart9.h"

#include "RTT.h"

#include "led.h"

#include <stdio.h>

#include <stdlib.h>

#include "coremark.h"

#include "ebtn_app.h"

FSP_CPP_HEADER

void R_BSP_WarmStart(bsp_warm_start_event_t event);

FSP_CPP_FOOTER

void coremark_main(void);

volatile uint8_t button_count = 0;

//RTC变量

/* rtc_time_t is an alias for the C Standard time.h struct 'tm' */

rtc_time_t set_time =

{

.tm_sec = 00, /* 秒,范围从 0 到 59 */

.tm_min = 05, /* 分,范围从 0 到 59 */

.tm_hour = 16, /* 小时,范围从 0 到 23*/

.tm_mday = 10, /* 一月中的第几天,范围从 1 到 31*/

.tm_mon = 6, /* 月份,范围从 0 到 11*/

.tm_year = 125, /* 自 1900 起的年数,2025为125*/

.tm_wday = 2, /* 一周中的第几天,范围从 0 到 6*/

// .tm_yday=0, /* 一年中的第几天,范围从 0 到 365*/

// .tm_isdst=0; /* 夏令时*/

};

//RTC闹钟变量

rtc_alarm_time_t set_alarm_time=

{

.time.tm_sec = 10, /* 秒,范围从 0 到 59 */

.time.tm_min = 30, /* 分,范围从 0 到 59 */

.time.tm_hour = 16, /* 小时,范围从 0 到 23*/

.time.tm_mday = 10, /* 一月中的第几天,范围从 1 到 31*/

.time.tm_mon = 6, /* 月份,范围从 0 到 11*/

.time.tm_year = 125, /* 自 1900 起的年数,2025为125*/

.time.tm_wday = 2, /* 一周中的第几天,范围从 0 到 6*/

.sec_match        =  1,
 .min_match        =  0,
 .hour_match       =  0,
 .mday_match       =  0,
 .mon_match        =  0,
 .year_match       =  0,
 .dayofweek_match  =  0,
};

//RTC回调函数

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;

}

void disp_0(void);

void disp_1(void);

void disp_2(void);

void disp_3(void);

void disp_4(void);

void disp_5(void);

void disp_6(void);

void disp_7(void);

void disp_8(void);

void disp_9(void);

void disp_num(uint8_t channel, uint8_t num);

void disp_num1(uint8_t channel, uint8_t num);

void disp_COL1(void);

void disp_DOT1(void);

/*******************************************************************************************************************//**

  • main() is generated by the RA Configuration editor and is used to generate threads if an RTOS is used. This function

  • is called by main() when no RTOS is used.

    **********************************************************************************************************************/

    void hal_entry(void)

    {

    /* TODO: add your own code here */

    fsp_err_t err;

    /* Open SLCDC driver */

    err = R_SLCDC_Open(&g_slcdc0_ctrl, &g_slcdc0_cfg);

    /* Handle any errors. This function should be defined by the user. */

    assert(FSP_SUCCESS == err);

    /* When using internal boost mode this delay is required to allow the boost circuit to charge. See RA4M1 User's

    • Manual (R01UH0887EJ0100) 8.2.18 "Segment LCD Source Clock Control Register (SLCDSCKCR)" for details. */

      R_BSP_SoftwareDelay(5, BSP_DELAY_UNITS_MILLISECONDS);

      /* Start SLCDC output */

      err = R_SLCDC_Start(&g_slcdc0_ctrl);

      assert(FSP_SUCCESS == err);

    /* Set Display Area of SLCDC driver.*/

    // err = R_SLCDC_SetDisplayArea(&g_slcdc0_ctrl, SLCDC_DISP_A);

    // assert(FSP_SUCCESS == err);

    //准备并写入段显示数据,第一个数码管显示1

    uint8_t segment_data_num1[] = {

    0x00,0x00,0x00,0x00,0x00,

    0x00,0x00,0x00,0x00,0x00,

    0x00,0x6

    };

    R_SLCDC_Write(&g_slcdc0_ctrl, 0, segment_data_num1, sizeof(segment_data_num1));

    R_BSP_SoftwareDelay (100, BSP_DELAY_UNITS_MILLISECONDS);
    //准备并写入段显示数据,第二个数码管显示2

    uint8_t segment_data_num2[] = {

    0xE,0x3};

    R_SLCDC_Write(&g_slcdc0_ctrl, 15, segment_data_num2, sizeof(segment_data_num2));

    R_BSP_SoftwareDelay (100, BSP_DELAY_UNITS_MILLISECONDS);
    //准备并写入段显示数据,第三个数码管显示3

    R_SLCDC_Modify(&g_slcdc0_ctrl, 22, 0xA, 0xF);

    R_SLCDC_Modify(&g_slcdc0_ctrl, 23, 0x7, 0xF);

    R_BSP_SoftwareDelay (100, BSP_DELAY_UNITS_MILLISECONDS);
    //准备并写入段显示数据,第四个数码管显示4

    R_SLCDC_Modify(&g_slcdc0_ctrl, 24, 0x3, 0xF);

    R_SLCDC_Modify(&g_slcdc0_ctrl, 29, 0x6, 0xF);

    R_BSP_SoftwareDelay (100, BSP_DELAY_UNITS_MILLISECONDS);
    //准备并写入段显示数据,第五个数码管显示5

    R_SLCDC_Modify(&g_slcdc0_ctrl, 30, 0xB, 0xF);

    R_SLCDC_Modify(&g_slcdc0_ctrl, 39, 0x5, 0xF);

    R_BSP_SoftwareDelay (100, BSP_DELAY_UNITS_MILLISECONDS);
    //准备并写入段显示数据,第六个数码管显示6

    R_SLCDC_Modify(&g_slcdc0_ctrl, 40, 0xF, 0xF);

    R_SLCDC_Modify(&g_slcdc0_ctrl, 41, 0x5, 0xF);

    R_BSP_SoftwareDelay (100, BSP_DELAY_UNITS_MILLISECONDS);
    UART9_Init();

    hal_systick_init();

    ebtn_APP_Key_INIT();

    / RTC开启 *****************/

    /* Initialize the RTC module*/

    err = R_RTC_Open(&g_rtc0_ctrl, &g_rtc0_cfg);
    /* Handle any errors. This function should be defined by the user. */

    assert(FSP_SUCCESS == err);
    /* Set the RTC clock source. Can be skipped if "Set Source Clock in Open" property is enabled. */

    R_RTC_ClockSourceSet(&g_rtc0_ctrl);

    /* R_RTC_CalendarTimeSet must be called at least once to start the RTC */

    R_RTC_CalendarTimeSet(&g_rtc0_ctrl, &set_time);

    /* Set the periodic interrupt rate to 1 second */

    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("\r\n欢迎来到瑞萨电子\r\n");

    printf("很高兴试用RA4L1开发板********\r\n");

    printf("串口输出打印 波特率115200\r\n\r\n");
    //清空0-41段

    uint8_t segment_data_num_off[41+1] ;

    for(int i=0;i<=41;i++)

    segment_data_num_off[i]=0;

    R_SLCDC_Write(&g_slcdc0_ctrl, 0, segment_data_num_off, sizeof(segment_data_num_off));

    R_BSP_SoftwareDelay (1000, BSP_DELAY_UNITS_MILLISECONDS);

    /*

    //全部点亮

    uint8_t segment_data_num_on[41+1] ;

    for(int i=0;i<=41;i++)

    segment_data_num_on[i]=0xf;

    R_SLCDC_Write(&g_slcdc0_ctrl, 0, segment_data_num_on, sizeof(segment_data_num_on));

    R_BSP_SoftwareDelay (1000, BSP_DELAY_UNITS_MILLISECONDS);

    */
    while (1)

    {

    if(rtc_flag)

    {

    R_RTC_CalendarTimeGet(&g_rtc0_ctrl, &get_time);//获取RTC计数时间

    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 年 %d 月 %d 日 %d 时 %d 分 %d 秒 第 %d 周\n",rtc_year+1900,rtc_month+1,rtc_day,rtc_hour,rtc_minute,rtc_second,rtc_week);

    disp_num(1, rtc_hour/10);disp_num(2, rtc_hour%10);
     	disp_num(3, rtc_minute/10);disp_num(4, rtc_minute%10);
     	disp_num(5, rtc_second/10);disp_num(6, rtc_second%10);
    
    
    
         }
     if(rtc_alarm_flag)
     {
         rtc_alarm_flag=0;
         printf("/************************Alarm Clock********************************/\\n");
     }
     R_BSP_SoftwareDelay(10U, BSP_DELAY_UNITS_MILLISECONDS);
    

    }

#if BSP_TZ_SECURE_BUILD

/* Enter non-secure code */

R_BSP_NonSecureEnter();

#endif

}
image.png

image.png

image.png

image.png

image.png

到此初始化完成

下面是RTC和段码显示屏核心功能函数,用来显示实时时间
image.png

先清空断码屏数据
image.png

image.png

while (1)
{
    if(rtc_flag)
    {
        R_RTC_CalendarTimeGet(&g_rtc0_ctrl, &get_time);//获取RTC计数时间
        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 年 %d 月 %d 日 %d 时 %d 分 %d 秒 第 %d 周\\n",rtc_year+1900,rtc_month+1,rtc_day,rtc_hour,rtc_minute,rtc_second,rtc_week);

	
	
		disp_num(1, rtc_hour/10);disp_num(2, rtc_hour%10);
		disp_num(3, rtc_minute/10);disp_num(4, rtc_minute%10);
		disp_num(5, rtc_second/10);disp_num(6, rtc_second%10);
	
	

        }
    if(rtc_alarm_flag)
    {
        rtc_alarm_flag=0;
        printf("/************************Alarm Clock********************************/\\n");
    }
    R_BSP_SoftwareDelay(10U, BSP_DELAY_UNITS_MILLISECONDS);

}

打开串口查看数据
image.png

和电脑右下角时间完全吻合
4dc4566f1df699e2a0b1c3779feb280.jpg

e5e16d93d6dc376bd5cb82840985125.jpg

详细细节,看我视频即可!!!!!!
——————————————————————————————————————————————————————
好了,我有完美了这个RTC实时时钟,做成了万年历,可以显示年月日,时分秒了。

原理是:我做了分屏切换,开机默认显示年月日,通过按键进行切换到时分秒,重复按键进行年月日时分秒循环切换!非常的完美了
详细代码如下:
while (1)
{
if(rtc_flag)
{
R_RTC_CalendarTimeGet(&g_rtc0_ctrl, &get_time);//获取RTC计数时间
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 年 %d 月 %d 日 %d 时 %d 分 %d 秒 第 %d 周\n",rtc_year+1900,rtc_month,rtc_day,rtc_hour,rtc_minute,rtc_second,rtc_week);

year = rtc_year+1900;
		year %= 100;
		if((time_count %2) == 0)//年月日
		{
			disp_num(1, year/10);disp_num(2, year%10);
			disp_num(3, rtc_month/10);disp_num(4, rtc_month%10);
			disp_num(5, rtc_day/10);disp_num(6, rtc_day%10);
		}
		if((time_count %2) == 1)//时分秒
		{
			disp_num(1, rtc_hour/10);disp_num(2, rtc_hour%10);
			disp_num(3, rtc_minute/10);disp_num(4, rtc_minute%10);
			disp_num(5, rtc_second/10);disp_num(6, rtc_second%10);
		}
			
	
		

        }
    if(rtc_alarm_flag)
    {
        rtc_alarm_flag=0;
        printf("/************************Alarm Clock********************************/\n");
    }
    R_BSP_SoftwareDelay(10U, BSP_DELAY_UNITS_MILLISECONDS);

image.png

通过按键来进行年月日和时分秒的切换,完美了!!!此贴终结
下面是2025年6月10日

52d7262023b21a52d0df8b373d2ff69.jpg

下面是17时23分19秒
d07a30c36678465be609b14a3d189c2.jpg
看底部视频

年月日时分秒完美切换

更多回帖

发帖
×
20
完善资料,
赚取积分