RTC功能是一种重要的功能。RA4E1也具有RTC功能,能计算秒、分、小时、星期、日期、月和年,其闰年补偿有效期达到 2100 年。本次测试使用上次的IIC接口的OLED作为时钟的显示。RTC功能是独立于MCU核心功能的,因此可以单独的使用时钟功能,在系统处于sleep状态时可以进行对芯片的唤醒。如果想使用RTC需要理解芯片的时钟设置。芯片的时钟具有8个时钟源,与RTC有关系的有两个时钟源,LOCO和外部时钟,都是32.768K时钟,内部的时钟计时精度较低,如果要求高的情况需要使用外部时钟源,本次测试使用LOCO时钟源。
Main Clock Oscillator (MOSC) |
主时钟振荡器(连接外部 8~24 MHz 高速晶振) |
Sub-Clock Oscillator (SOSC) |
副时钟振荡器(连接外部 32.768 kHz 低速晶振) |
HOCO |
高速片上振荡器 |
MOCO |
中速片上振荡器 |
LOCO |
低速片上振荡器 |
PLL |
PLL输出 |
PLL2 |
PLL2输出 |
IWDT-dedicated clock |
独立看门狗时钟 |
JTAG clock |
JTAG (TCK) 时钟 |
SWD clock |
SWD (SWCLK) 时钟 |
使用设置工具生成项目
设置时钟源为LOCO,还有中断响应函数。
主要的设置程序在rtc_ep.c中,
/***********************************************************************************************************************
* File Name : rtc_ep.c
* Description : Contains data structures and functions used in rtc_ep.c.
**********************************************************************************************************************/
/***********************************************************************************************************************
* Copyright (C) 2020 Renesas Electronics Corporation. All rights reserved.
*
* This file is part of Renesas RA Flex Software Package (FSP)
*
* The contents of this file (the "contents") are proprietary and confidential to Renesas Electronics Corporation
* and/or its licensors ("Renesas") and subject to statutory and contractual protections.
*
* This file is subject to a Renesas FSP license agreement. Unless otherwise agreed in an FSP license agreement with
* Renesas: 1) you may not use, copy, modify, distribute, display, or perform the contents; 2) you may not use any name
* or mark of Renesas for advertising or publicity purposes or in connection with your use of the contents; 3) RENESAS
* MAKES NO WARRANTY OR REPRESENTATIONS ABOUT THE SUITABILITY OF THE CONTENTS FOR ANY PURPOSE; THE CONTENTS ARE PROVIDED
* "AS IS" WITHOUT ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
* PARTICULAR PURPOSE, AND NON-INFRINGEMENT; AND 4) RENESAS SHALL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL, OR
* CONSEQUENTIAL DAMAGES, INCLUDING DAMAGES RESULTING FROM LOSS OF USE, DATA, OR PROJECTS, WHETHER IN AN ACTION OF
* CONTRACT OR TORT, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THE CONTENTS. Third-party contents
* included in this file may be subject to different terms.
**********************************************************************************************************************/
#include "common_utils.h"
#include "rtc_ep.h"
/*******************************************************************************************************************//**
* @addtogroup rtc_ep
* @{
**********************************************************************************************************************/
#define BUFFER_SIZE_DOWN (32)
/* Variable to store time */
static rtc_time_t g_set_time = {
.tm_hour = RESET_VALUE,
.tm_isdst = RESET_VALUE,
.tm_mday = RESET_VALUE,
.tm_min = RESET_VALUE,
.tm_mon = RESET_VALUE,
.tm_sec = RESET_VALUE,
.tm_wday = RESET_VALUE,
.tm_yday = RESET_VALUE,
.tm_year = RESET_VALUE,
};
rtc_time_t g_present_time = {
.tm_hour = RESET_VALUE,
.tm_isdst = RESET_VALUE,
.tm_mday = RESET_VALUE,
.tm_min = RESET_VALUE,
.tm_mon = RESET_VALUE,
.tm_sec = RESET_VALUE,
.tm_wday = RESET_VALUE,
.tm_yday = RESET_VALUE,
.tm_year = RESET_VALUE,
};
static uint32_t set_time_flag = RESET_FLAG; //Flag to be set on successful RTC Calendar setting
static void rtc_date_time_conversion(rtc_time_t * time, unsigned char read_buffer[]);
extern volatile uint32_t g_alarm_irq_flag;
extern volatile uint32_t g_periodic_irq_flag;
extern volatile uint32_t g_invalid_sequence;
/*******************************************************************************************************************//**
* [url=home.php?mod=space&uid=159083]@brief[/url] This functions initializes RTC module.
* @param[IN] None
* @retval FSP_SUCCESS Upon successful open of RTC module
* @retval Any Other Error code apart from FSP_SUCCESS Unsuccessful open
**********************************************************************************************************************/
fsp_err_t rtc_init(void)
{
fsp_err_t err = FSP_SUCCESS; // Error status
/* Open RTC module */
err = R_RTC_Open(&g_rtc_ctrl, &g_rtc_cfg);
/* Handle error */
if (FSP_SUCCESS != err)
{
}
return err;
}
/*******************************************************************************************************************//**
* @brief This functions sets the Calendar time provided by user.
* @param[IN] None
* @retval FSP_SUCCESS Upon successful Calendar time set
* @retval Any Other Error code apart from FSP_SUCCESS Unsuccessful Calendar time set
**********************************************************************************************************************/
fsp_err_t set_rtc_calendar_time(void)
{
fsp_err_t err = FSP_SUCCESS; // Error status
unsigned char read_time[BUFFER_SIZE_DOWN] = {NULL_CHAR};
/* Modify user provided date and time to standard format */
rtc_date_time_conversion(&g_set_time, &read_time[0]);
/* Set the time provided by user */
err = R_RTC_CalendarTimeSet(&g_rtc_ctrl, &g_set_time);
/* Handle error */
if (FSP_SUCCESS != err)
{
return err;
}
/* Get the current Calendar time */
err = R_RTC_CalendarTimeGet(&g_rtc_ctrl, &g_present_time);
/* Handle error */
if (FSP_SUCCESS != err)
{
return err;
}
/* Modify the date in standard format to user readable format */
rtc_date_readability_update(&g_present_time);
set_time_flag = SET_FLAG;
return err;
}
/*******************************************************************************************************************//**
* @brief This functions sets the alarm time provided by user.
* @param[IN] None
* @retval FSP_SUCCESS Upon successful Calendar alarm set
* @retval Any Other Error code apart from FSP_SUCCESS Unsuccessful Calendar alarm set
**********************************************************************************************************************/
fsp_err_t set_rtc_calendar_alarm(void)
{
fsp_err_t err = FSP_SUCCESS; // Error status
rtc_alarm_time_t alarm_time_set =
{
.sec_match = RESET_VALUE,
.min_match = RESET_VALUE,
.hour_match = RESET_VALUE,
.mday_match = RESET_VALUE,
.mon_match = RESET_VALUE,
.year_match = RESET_VALUE,
.dayofweek_match = RESET_VALUE,
};
rtc_alarm_time_t alarm_time_get =
{
.sec_match = RESET_VALUE,
.min_match = RESET_VALUE,
.hour_match = RESET_VALUE,
.mday_match = RESET_VALUE,
.mon_match = RESET_VALUE,
.year_match = RESET_VALUE,
.dayofweek_match = RESET_VALUE,
};
unsigned char read_alarm[BUFFER_SIZE_DOWN] = {NULL_CHAR};
/*Set alarm only if proper RTC Calendar date and Time is set */
if (SET_FLAG == set_time_flag)
{
/* Set the flags for which the alarm has to be generated */
alarm_time_set.hour_match = false;
alarm_time_set.min_match = false;
alarm_time_set.sec_match = true;
alarm_time_set.mday_match = false;
alarm_time_set.mon_match = false;
alarm_time_set.year_match = false;
/* Reading time value for which alarm has to be generated */
/* Modify user provided time value to standard format */
alarm_time_set.time.tm_sec = (((read_alarm[0] - ASCII_ZERO) * PLACE_VALUE_TEN )+ (read_alarm[1] - ASCII_ZERO));
/* Set the alarm time provided by user*/
err = R_RTC_CalendarAlarmSet(&g_rtc_ctrl, &alarm_time_set);
/* Handle error */
if (FSP_SUCCESS != err)
{
return err;
}
/* Get the alarm time */
err = R_RTC_CalendarAlarmGet(&g_rtc_ctrl, &alarm_time_get);
/* Handle error */
if (FSP_SUCCESS != err)
{
return err;
}
}
else
{
/* Set this flag to notify the user to provide required options */
g_invalid_sequence = SET_FLAG;
}
return err;
}
/*******************************************************************************************************************//**
* @brief This functions sets the periodic interrupt rate provided by user.
* @param[IN] None
* @retval FSP_SUCCESS Upon successful periodic interrupt rate set
* @retval Any Other Error code apart from FSP_SUCCESS Unsuccessful periodic interrupt rate set
**********************************************************************************************************************/
fsp_err_t set_rtc_periodic_rate(void)
{
fsp_err_t err = FSP_SUCCESS; // Error status
/* Enable periodic interrupt rate */
err = R_RTC_PeriodicIrqRateSet(&g_rtc_ctrl, RTC_PERIODIC_IRQ_SELECT_1_SECOND);
/* Handle error */
if (FSP_SUCCESS != err)
{
}
return err;
}
/*******************************************************************************************************************//**
* @brief This functions gets the current RTC time.
* @param[IN] None
* @retval FSP_SUCCESS Upon successful current RTC time get
* @retval Any Other Error code apart from FSP_SUCCESS Unsuccessful current RTC time get
**********************************************************************************************************************/
fsp_err_t get_rtc_calendar_time(void)
{
fsp_err_t err = FSP_SUCCESS; // Error status
/* Get the current RTC Calendar time */
err = R_RTC_CalendarTimeGet(&g_rtc_ctrl, &g_present_time);
/* Handle error */
if (FSP_SUCCESS != err)
{
return err;
}
/* Modify the date in standard format to user readable format */
rtc_date_readability_update(&g_present_time);
return err;
}
/*******************************************************************************************************************//**
* @brief This functions modifies the date in readable format to the user.
* @param[IN] time date to be modified
* @retval None
**********************************************************************************************************************/
void rtc_date_readability_update(rtc_time_t * time)
{
time->tm_mon += MON_ADJUST_VALUE;
time->tm_year += YEAR_ADJUST_VALUE;
}
/*******************************************************************************************************************//**
* @brief This functions modifies the user input to rtc date and time.
* @param[IN] time date and time to be modified
* @param[IN] read_buffer Buffer that contains user input time values
* @retval None
**********************************************************************************************************************/
static void rtc_date_time_conversion(rtc_time_t * time, unsigned char read_buffer[])
{
/* User is expected to enter Date and Time in DD:MM:YYYY HH:MM:SS format. This User input in the buffer is processed
* using the following conversion, where ASCII value is converted to integer value and stored in the RTC time structure.
* According to DD:MM:YYYY HH:MM:SS format, different array index values are used. */
time->tm_mday = (((read_buffer[0] - ASCII_ZERO) * PLACE_VALUE_TEN) + (read_buffer[1] - ASCII_ZERO));
time->tm_mon = ((((read_buffer[3] - ASCII_ZERO) * PLACE_VALUE_TEN) + (read_buffer[4] - ASCII_ZERO))) - MON_ADJUST_VALUE;
time->tm_year = (((read_buffer[6] - ASCII_ZERO) * PLACE_VALUE_THOUSAND) +
((read_buffer[7] - ASCII_ZERO )* PLACE_VALUE_HUNDRED) +
((read_buffer[8] - ASCII_ZERO) * PLACE_VALUE_TEN) + (read_buffer[9] - ASCII_ZERO)) - YEAR_ADJUST_VALUE;
time->tm_hour = (((read_buffer[11] - ASCII_ZERO) * PLACE_VALUE_TEN) + (read_buffer[12] - ASCII_ZERO));
time->tm_min = (((read_buffer[14] - ASCII_ZERO) * PLACE_VALUE_TEN) + (read_buffer[15] - ASCII_ZERO));
time->tm_sec = (((read_buffer[17] - ASCII_ZERO) * PLACE_VALUE_TEN )+ (read_buffer[18] - ASCII_ZERO));
}
/*******************************************************************************************************************//**
* @brief RTC callback function.
* @param[in] p_args
* @retval None
**********************************************************************************************************************/
void rtc_callback(rtc_callback_args_t *p_args)
{
if(RTC_EVENT_ALARM_IRQ == p_args->event)
{
g_alarm_irq_flag = SET_FLAG;
}
else
{
g_periodic_irq_flag = SET_FLAG;
}
}
/*******************************************************************************************************************//**
* @brief This function closes opened RTC module before the project ends up in an Error Trap.
* @param[IN] None
* @retval None
**********************************************************************************************************************/
void rtc_deinit(void)
{
fsp_err_t err = FSP_SUCCESS;
/* Close RTC module */
err = R_RTC_Close(&g_rtc_ctrl);
/* Handle error */
if (FSP_SUCCESS != err)
{
/* RTC Close failure message */
}
}
/*******************************************************************************************************************//**
* @} (end addtogroup rtc_ep)
**********************************************************************************************************************/
其中的重要的是rtc_callback()函数,这个函数是中断后设置工作标记的。应用中的函数根据中断标记进行工作。主要的应用程序在hal_entr()函数中
/* TODO: add your own code here */
char timeStr[10]={0};
err = R_IIC_MASTER_Open(&g_i2c_master0_ctrl, &g_i2c_master0_cfg);
assert(FSP_SUCCESS == err);
WriteCmd();//OLED???
OLED_Clear();//??
OLED_ShowString(0,0,"EEWORLD",16);
OLED_ShowString(0,2,"RA4E1 ",16);
err = rtc_init();
set_rtc_periodic_rate();
err = set_rtc_calendar_time();
if (FSP_SUCCESS != err)
{}
for(;;)
{
if (SET_FLAG == g_alarm_irq_flag)
{
g_alarm_irq_flag = RESET_FLAG;
}
if (SET_FLAG == g_periodic_irq_flag)
{
get_rtc_calendar_time();
sprintf(timeStr,"%02d:%02d:%02d",g_present_time.tm_hour,g_present_time.tm_min,g_present_time.tm_sec);
OLED_ShowString(0,4,(uint8_t *)timeStr,16);
g_periodic_irq_flag = RESET_FLAG;
}
}
程序运行后的效果:
|