【简介】
S32K146 芯片内部集成了RTC 定时器,我们可以使用内部的RTC 来实现实时时钟的使用。RTC 模块的特性描述如下:
【S32DS时钟配置】
RTC 模块有多路时钟源可以配置,本地使用LPO128K 的四分频作为RTC 的工作时钟,配置如下
【S32DS RTC 参数配置】
生成如下初始化代码
/*********************************************************************************************************************** * This file was generated by the S32 Configuration Tools. Any manual edits made to this file * will be overwritten if the respective S32 Configuration Tools is used to update this file. **********************************************************************************************************************/ /* clang-format off */ /* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* !!GlobalInfo product: Peripherals v14.0 processor: S32K146 package_id: S32K146_LQFP144 mcu_data: s32sdk_s32k1xx_rtm_401 processor_version: 0.0.0 functionalGroups: - name: BOARD_InitPeripherals UUID: 2d0c0af7-dbe7-4f00-821a-837510d6ab4e called_from_default_init: true selectedCore: core0 * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ /* clang-format on */ /******************************************************************************* * Included files ******************************************************************************/ #include "peripherals_rtc_1.h" /******************************************************************************* * rtc_1 initialization code ******************************************************************************/ /* clang-format off */ /* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* instance: - name: 'rtc_1' - type: 'rtc_config' - mode: 'rtcDriver' - custom_name_enabled: 'false' - type_id: 'rtc' - functional_group: 'BOARD_InitPeripherals' - peripheral: 'RTC' - config_sets: - rtc_driver: - rtcInitConfig: - 0: - init: - name: 'rtc_1InitCfg0' - readonly: 'true' - updateEnable: 'false' - nonSupervisorAccessEnable: 'false' - compensationEnable: 'false' - compensationInterval: '0' - compensation: '0' - clockSelect: 'RTC_CLK_SRC_LPO_1KHZ' - clockOutConfig: 'RTC_CLKOUT_DISABLED' - date: - 0: - year: '1970' - month: '1' - day: '1' - hour: '0' - minutes: '0' - seconds: '0' - rtcLockConfig: - 0: - enableCfg: 'true' - name: 'rtc_1LockCfg0' - readonly: 'true' - lockRegisterLock: 'false' - statusRegisterLock: 'false' - controlRegisterLock: 'false' - timeCompensationRegisterLock: 'false' - rtcAlarmConfig: - 0: - enableCfg: 'true' - name: 'rtc_1AlarmCfg0' - alarmTime: - 0: - year: '1970' - month: '1' - day: '1' - hour: '0' - minutes: '0' - seconds: '0' - repeat: 'false' - repeatForever: 'false' - repetitionInterval: '0' - numberOfRepeats: '0' - alarmIntEnable: 'false' - alarmCallback: 'NULL' - rtcTSIConfig: - 0: - enableCfg: 'true' - name: 'rtc_1SecIntCfg0' - secondIntConfig: 'RTC_INT_1HZ' - secondIntEnable: 'false' - rtcSecondsCallback: 'NULL' - rtcFaultConfig: - 0: - enableCfg: 'true' - name: 'rtc_1FaultCfg0' - overflowIntEnable: 'false' - timeInvalidIntEnable: 'false' - rtcCallback: 'NULL' * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ /* clang-format on */ /** * @page misra_violations MISRA-C:2012 violations * * * @section [global] * Violates MISRA 2012 Advisory Rule 2.5, Global macro not referenced. * The global macro will be used in function call of the module. * @section [global] * Violates MISRA 2012 Advisory Rule 8.7, External variable could be made static. * The external variables will be used in other source files in application code. * */ /* * RTC Initialization configurations */ /*! rtc_1InitCfg0 instance initialization configuration */ const rtc_init_config_t rtc_1InitCfg0 = { .updateEnable = false, .nonSupervisorAccessEnable = false, .compensationInterval = 0U, .compensation = 0, .clockSelect = RTC_CLK_SRC_LPO_1KHZ, .clockOutConfig = RTC_CLKOUT_DISABLED }; /*! rtc_1InitCfg0_StartTime Initial Time and Date */ const rtc_timedate_t rtc_1InitCfg0_StartTime = { .year = 1970U, .month = 1U, .day = 1U, .hour = 0U, .minutes = 0U, .seconds = 0U }; /* * RTC Register Lock configurations */ /*! rtc_1LockCfg0 register lock configuration */ const rtc_register_lock_config_t rtc_1LockCfg0 = { .lockRegisterLock = false, .statusRegisterLock = false, .controlRegisterLock = false, .timeCompensationRegisterLock = false }; /* * RTC Alarm configurations */ /*! rtc_1AlarmCfg0 alarm configuration */ rtc_alarm_config_t rtc_1AlarmCfg0 = { .alarmTime = { .year = 1970U, .month = 1U, .day = 1U, .hour = 0U, .minutes = 0U, .seconds = 0U }, .repeatForever = false, .repetitionInterval = 0UL, .numberOfRepeats = 0UL, .alarmIntEnable = false, .callbackParams = NULL, .alarmCallback = NULL }; /* * RTC Time Seconds Interrupt configurations */ /*! rtc_1SecIntCfg0 time seconds configuration */ rtc_seconds_int_config_t rtc_1SecIntCfg0 = { .secondIntConfig = RTC_INT_1HZ, .secondIntEnable = false, .secondsCallbackParams = NULL, .rtcSecondsCallback = NULL }; /* * RTC Fault interrupt configurations */ /*! rtc_1FaultCfg0 fault configuration */ rtc_interrupt_config_t rtc_1FaultCfg0 = { .overflowIntEnable = false, .timeInvalidIntEnable = false, .callbackParams = NULL, .rtcCallback = NULL };
【代码验证】
添加如下代码初始化RTC
static int rtc_init(void) { status_t ret; /* Call the init function */ ret = RTC_DRV_Init(RTC_1, &rtc_1InitCfg0); if(ret != STATUS_SUCCESS) { LOG_E("RTC init failed %x.",ret); } else { LOG_I("RTC init OK."); } /* Set the time and date */ ret = RTC_DRV_SetTimeDate(RTC_1, &rtc_1InitCfg0_StartTime); if(ret != STATUS_SUCCESS) { LOG_E("RTC set time failed %x.",ret); } else { LOG_I("RTC set time OK."); } /* Start RTC counter */ ret = RTC_DRV_StartCounter(RTC_1); if(ret != STATUS_SUCCESS) { LOG_E("RTC start failed %x.",ret); } else { LOG_I("RTC start OK."); } return 1; } INIT_BOARD_EXPORT_LEVEL1(rtc_init);
添加如下代码输出RTC时间
unsigned int date(char argc,char *argv[]) { status_t ret; rtc_timedate_t currentTime; ret = RTC_DRV_GetCurrentTimeDate ( RTC_1, ¤tTime ); if(ret != STATUS_SUCCESS) { LOG_E("RTC start failed %x.",ret); } else { LOG_I("%d:%d:%d %d:%d:%d",currentTime.year,currentTime.month,currentTime.day, currentTime.hour,currentTime.minutes,currentTime.seconds); } return 0; }
连续读取RTC 时间发现RTC 计数器已经在持续变化更新。
更新测试代码添加RTC 时间设置,设置时间后读取RTC 时间已经按预期的设置成功
unsigned int date(char argc,char *argv[]) { status_t ret; rtc_timedate_t currentTime; if(argc == 1) { ret = RTC_DRV_GetCurrentTimeDate ( RTC_1, ¤tTime ); if(ret != STATUS_SUCCESS) { LOG_E("RTC read failed %x.",ret); } else { LOG_I("%d:%d:%d %d:%d:%d",currentTime.year,currentTime.month,currentTime.day, currentTime.hour,currentTime.minutes,currentTime.seconds); } } if(argc == 7) { ret = RTC_DRV_StopCounter(RTC_1); if(ret != STATUS_SUCCESS) { LOG_E("RTC stop failed %x.",ret); } currentTime.year = atoi(argv[1]); currentTime.month = atoi(argv[2]); currentTime.day = atoi(argv[3]); currentTime.hour = atoi(argv[4]); currentTime.minutes = atoi(argv[5]); currentTime.seconds = atoi(argv[6]); ret = RTC_DRV_SetTimeDate(RTC_1, ¤tTime); if(ret != STATUS_SUCCESS) { LOG_E("RTC set time failed %x.",ret); } ret = RTC_DRV_StartCounter(RTC_1); if(ret != STATUS_SUCCESS) { LOG_E("RTC start failed %x.",ret); } } return 0; }