1 Introducing RTC timer
The RTC timer is called the real time clock. There are many timers inside the CPU, such as the watchdog WDT, PWM timer, high-precision timer Timer, etc., which only run when "started" or "powered on", and stop when the power is off. Of course, if the clock cannot track time continuously, it must be set manually. Then there is no way to automatically count the time after shutting down. The essence of a timer is a counter, which can count up or down. RTC has a power supply that is separate from the host, such as a button battery (backup battery). Even if the host power is turned off, it maintains the counting and timing function. This is why the time on our mobile phones can remain accurate after turning off. For example, the old Nokia mobile phones in the past will not be accurate if the battery is removed, because the RTC power supply is cut off and it cannot count. The counter of the RTC timer will be cleared to 0, and the current time needs to be set manually. RTC generally uses a button battery to power the external crystal oscillator and circuit. !
2 RTC Timer Principle
Taking the RTC timer of the IMX6U chip as an example, there is also an RTC module inside the I.MX6U, but it is not called "RTC", but "SNVS". The RTC module structure diagram is as follows:
SNVS is divided into two sub-modules: SNVS_HP and SNVS_LP, namely the high power domain (SNVS_HP) and the low power domain (SNVS_LP). The power sources of these two domains are as follows:
SNVS_LP: A dedicated always-powered-on power domain that can be powered by both the system main power supply and the backup power supply. SNVS_HP: System (chip) power supply.
After the system main power is cut off, SNVS_HP will also be powered off, but with the support of the backup power supply, SNVS_LP will not be powered off, and SNVS_LP is isolated from the chip reset, so the values of the registers related to SNVS_LP will be kept, that is, the low power domain is not affected by the system power supply. The meanings of the serial numbers in the above figure are as follows: ①, VDD_HIGH_IN is the main power supply of the system (chip), this power supply will be supplied to SNVS_HP and SNVS_LP at the same time. ②, VDD_SNVS_IN is the power supply powered by the button battery, this power supply will only be supplied to SNVS_LP, ensuring that SNVS_LP will continue to run after the system main power supply VDD_HIGH_IN is powered off. ③, SNVS_HP part. ④, SNVS_LP part, this part has an SRTC, this is the RTC to be used. SRTC requires a 32.768KHz clock from the outside world. The 32.768KHz crystal oscillator on the I.MX6U-ALPHA core board provides this clock.
3 RTC Timer Registers
SNVS_SRTCMR[14:0] represents the high 15 bits of the SRTC counter SNVS_SRTCLR[31:15] represents the low 17 bits of the SRTC counter Note: The starting point is 0:0:00 on January 1, 1970, and the total number of seconds that have passed can be added to get the current time point. SNVS_HPCOMR[31], NPSWA_EN bit, non-privileged software access control bit, if non-privileged software wants to access SNVS, this bit must be 1. SNVS_LPCR[0], SRTC_ENV bit, enables the STC counter.
4 RTC bare metal source code display
The NXP official SDK package is written for I.MX6ULL, so the registers in the structure SNVS_Type in the file MCIMX6Y2.h are incomplete. We need to add the registers required for the experiment in this chapter and modify SNVS_Type to be as follows:
/*!
* @addtogroup SNVS_Peripheral_Access_Layer SNVS Peripheral Access Layer
* @{
*/
/** SNVS - Register Layout Typedef */
/* zuozhongkai 2018/12/13 */
typedef struct {
__IO uint32_t HPLR; /**< SNVS_HP Lock register, offset: 0x0 */
__IO uint32_t HPCOMR; /**< SNVS_HP Command register, offset: 0x4 */
__IO uint32_t HPCR; /**< SNVS_HP Control register, offset: 0x8 */
__IO uint32_t HPSICR; /**< SNVS_HP Control register, offset: 0x8 */
__IO uint32_t HPSVCR;
__IO uint32_t HPSR;
__IO uint32_t HPSVSR;
__IO uint32_t HPHACIVR;
__IO uint32_t HPHACR;
__IO uint32_t HPRTCMR;
__IO uint32_t HPRTCLR;
__IO uint32_t HPTAMR;
__IO uint32_t HPTALR;
__IO uint32_t LPLR;
__IO uint32_t LPCR;
__IO uint32_t LPMKCR;
__IO uint32_t LPSVCR;
__IO uint32_t LPTGFCR;
__IO uint32_t LPTDCR;
__IO uint32_t LPSR;
__IO uint32_t LPSRTCMR;
__IO uint32_t LPSRTCLR;
__IO uint32_t LPTAR;
__IO uint32_t LPSMCMR;
__IO uint32_t LPSMCLR;
}SNVS_Type;
bsp_rtc.h
#ifndef _BSP_RTC_H
#define _BSP_RTC_H
/****************************************************** ****************
Copyright © zuozhongkai Co., Ltd. 1998-2019. All rights reserved.
File name: bsp_rtc.c
Author : Zuo Zhongkai
Version: V1.0
Description: RTC driver header file.
Others: None
Forum : www.wtmembed.com
Log: First version V1.0 2019/1/3 Created by Zuo Zhongkai
*************************************************** *************/
#include "imx6ul.h"
/* Related macro definitions */
#define SECONDS_IN_A_DAY (86400) /* 86400 seconds in a day */
#define SECONDS_IN_A_HOUR (3600) /* 3600 seconds in an hour */
#define SECONDS_IN_A_MINUTE (60) /* 60 seconds in a minute */
#define DAYS_IN_A_YEAR (365) /* 365 days in a year */
#define YEAR_RANGE_START (1970) /* Start year 1970 */
#define YEAR_RANGE_END (2099) /* End year 2099 */
/* Date and time structure*/
struct rtc_datetime
{
unsigned short year; /* Range: 1970 ~ 2099 */
unsigned char month; /* Range: 1 ~ 12 */
unsigned char day; /* Range: 1 ~ 31 (different months, different days).*/
unsigned char hour; /* Range: 0 ~ 23 */
unsigned char minute; /* Range: 0 ~ 59 */
unsigned char second; /* Range: 0 ~ 59 */
};
/* Function declaration */
void rtc_init(void);
void rtc_enable(void);
void rtc_disable(void);
unsigned int rtc_coverdate_to_seconds(struct rtc_datetime *datetime);
unsigned int rtc_getseconds(void);
void rtc_setdatetime(struct rtc_datetime *datetime);
void rtc_getdatetime(struct rtc_datetime *datetime);
#endif
bsp_rtc.c
/****************************************************** ****************
Copyright © zuozhongkai Co., Ltd. 1998-2019. All rights reserved.
File name: bsp_rtc.c
Author : Zuo Zhongkai
Version: V1.0
Description: RTC driver file.
Others: None
Forum : www.wtmembed.com
Log: First version V1.0 2019/1/3 Created by Zuo Zhongkai
*************************************************** *************/
#include "bsp_rtc.h"
#include "stdio.h"
/*
* Description: Initialize RTC
*/
void rtc_init(void)
{
/*
* Set the HPCOMR register
* bit[31] 1: Allow access to the SNVS register, must be set to 1
* bit[8] 1: This bit is set to 1. You need to sign the NDA agreement to see the detailed description of this bit.
* It is OK not to set it to 1
*/
SNVS->HPCOMR |= (1 << 31) | (1 << 8);
#if 0
struct rtc_datetime rtcdate;
rtcdate.year = 2018U;
rtcdate.month = 12U;
rtcdate.day = 13U;
rtcdate.hour = 14U;
rtcdate.minute = 52;
rtcdate.second = 0;
rtc_setDatetime(&rtcdate); //Initialize time and date
#endif
rtc_enable(); //Enable RTC
}
/*
* Description: Enable RTC
*/
void rtc_enable(void)
{
/*
* Set LPCR register bit 0 to 1 to enable RTC
*/
SNVS->LPCR |= 1 << 0;
while(!(SNVS->LPCR & 0X01));//Wait for enabling to complete
}
/*
* Description: Turn off RTC
*/
void rtc_disable(void)
{
/*
* Set LPCR register bit0 to 0 to turn off RTC
*/
SNVS->LPCR &= ~(1 << 0);
while(SNVS->LPCR & 0X01); //Wait for shutdown to complete
}
/*
* @description: Determines whether the specified year is a leap year. The leap year conditions are as follows:
* @param - year: the year to be judged
* @return: 1 is a leap year, 0 is not a leap year
*/
unsigned char rtc_isleapyear(unsigned short year)
{
unsigned char value=0;
if(year % 400 == 0)
value = 1;
else
{
if((year % 4 == 0) && (year % 100 != 0))
value = 1;
else
value = 0;
}
return value;
}
/*
* @description: Convert time to seconds
* @param - datetime: The date and time to convert.
* @return: the converted seconds
*/
unsigned int rtc_coverdate_to_seconds(struct rtc_datetime *datetime)
{
unsigned short i = 0;
unsigned int seconds = 0;
unsigned int days = 0;
unsigned short monthdays[] = {0U, 0U, 31U, 59U, 90U, 120U, 151U, 181U, 212U, 243U, 273U, 304U, 334U};
for(i = 1970; i < datetime->year; i++)
{
days += DAYS_IN_A_YEAR; /* Ordinary year, 365 days per year*/
if(rtc_isleapyear(i)) days += 1;/* add one more day in leap year */
}
days += monthdays[datetime->month];
if(rtc_isleapyear(i) && (datetime->month >= 3)) days += 1;/* If it is a leap year and the current month is greater than or equal to March, add one day*/
days += datetime->day - 1;
seconds = days * SECONDS_IN_A_DAY +
datetime->hour * SECONDS_IN_A_HOUR +
datetime->minute * SECONDS_IN_A_MINUTE +
datetime->second;
return seconds;
}
/*
* @description: Set time and date
* @param - datetime: the date and time to set
* @return : None
*/
void rtc_setdatetime(struct rtc_datetime *datetime)
{
unsigned int seconds = 0;
unsigned int tmp = SNVS->LPCR;
rtc_disable(); /* Be sure to turn off RTC before setting registers HPRTCMR and HPRTCLR */
/* Convert the time to seconds first */
seconds = rtc_coverdate_to_seconds(datetime);
SNVS->LPSRTCMR = (unsigned int)(seconds >> 17); /* Set the upper 16 bits */
SNVS->LPSRTCLR = (unsigned int)(seconds << 15); /* Set ground 16 bits */
/* If the RTC was turned on before, you need to turn it on again after setting the RTC time */
Previous article:IMX6ULL bare metal -2-PWM timer
Next article:s3c2440 bare metal - resistive touch screen - 7 - touch screen calibration test and optimization
- Popular Resources
- Popular amplifiers
- Learn ARM development(16)
- Learn ARM development(17)
- Learn ARM development(18)
- Embedded system debugging simulation tool
- A small question that has been bothering me recently has finally been solved~~
- Learn ARM development (1)
- Learn ARM development (2)
- Learn ARM development (4)
- Learn ARM development (6)
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- LED chemical incompatibility test to see which chemicals LEDs can be used with
- Application of ARM9 hardware coprocessor on WinCE embedded motherboard
- What are the key points for selecting rotor flowmeter?
- LM317 high power charger circuit
- A brief analysis of Embest's application and development of embedded medical devices
- Single-phase RC protection circuit
- stm32 PVD programmable voltage monitor
- Introduction and measurement of edge trigger and level trigger of 51 single chip microcomputer
- Improved design of Linux system software shell protection technology
- What to do if the ABB robot protection device stops
- CGD and Qorvo to jointly revolutionize motor control solutions
- CGD and Qorvo to jointly revolutionize motor control solutions
- Keysight Technologies FieldFox handheld analyzer with VDI spread spectrum module to achieve millimeter wave analysis function
- Infineon's PASCO2V15 XENSIV PAS CO2 5V Sensor Now Available at Mouser for Accurate CO2 Level Measurement
- Advanced gameplay, Harting takes your PCB board connection to a new level!
- Advanced gameplay, Harting takes your PCB board connection to a new level!
- A new chapter in Great Wall Motors R&D: solid-state battery technology leads the future
- Naxin Micro provides full-scenario GaN driver IC solutions
- Interpreting Huawei’s new solid-state battery patent, will it challenge CATL in 2030?
- Are pure electric/plug-in hybrid vehicles going crazy? A Chinese company has launched the world's first -40℃ dischargeable hybrid battery that is not afraid of cold
- Design of frequency sweeper using digital frequency synthesis technology, FPGA and single chip microcomputer
- Bluetooth MESH technology makes up for the shortcomings of networking
- Some Problems with Differential Circuits
- Analog input
- [Sipeed LicheeRV 86 Panel Review] 10-Video Playback Test
- May Day event is online! Let's do a "labor" transformation of old things together!
- Software - Can I use the Breaking Master on my computer to install Allegro 16.6 and 17.4 at the same time?
- CC3120 Wireless Network Processor BoosterPack Plug-in Module
- Simulink and ModelSim co-simulation to realize BLDC six-step square wave closed-loop control system
- [NUCLEO-L552ZE review] + driving LCD19264 display