IMX6ULL裸机-1-RTC定时器

发布者:EnchantedMagic最新更新时间:2024-07-03 来源: elecfans关键字:实时时钟 手机看文章 扫描二维码
随时随地手机看文章

1 引入RTC定时器

RTC定时器被叫做实时时钟(real time clock)。 CPU内部有很多定时器,像看门狗WDT,PWM定时器,高精度定时器Timer等等, 只在“启动”即“通电时”运行,断电时停止。当然,如果时钟不能连续跟踪时间,则必须手动设置。那么当关机后就没办法自动计数统计时间了。 定时器的本质就是计数器,有向上计数,也有向下计数。RTC有一个与主机单独分离的电源,如纽扣电池(备用电池),即使主机电源关闭,它也保持计数定时功能。这也是为什么我们手机关机后时间还能保持准确。再比如以前的老诺基亚手机,拆掉电池就时间不准了,因为rtc电源被切断了,无法在计数,RTC定时器的计数器会被清0,需要手动设置当前时间。 RTC一般都是用纽扣电池给外部晶振和电路供电。 !

2 RTC定时器原理

以IMX6U芯片的RTC定时器为例,I.MX6U 内部也有 个 RTC 模块,但是不叫作“RTC”,而是叫做“SNVS”。 RTC模块结构图如下:


SNVS 分为两个子模块:SNVS_HP 和 SNVS_LP,也就是高功耗域(SNVS_HP)和低功耗域(SNVS_LP),这两个域的电源来源如下:

SNVS_LP:专用的 always-powered-on 电源域,系统主电源和备用电源都可以为其供电。
SNVS_HP:系统(芯片)电源。

系统主电源断电以后 SNVS_HP 也会断电,但是在备用电源支持下,SNVS_LP 是不会断电的,而且 SNVS_LP 是和芯片复位隔离开的,因此 SNVS_LP 相关的寄存器的值会一直保存着, 也就是low Power Domain是不受系统电源影响。 上图各个序号含义如下: ①、VDD_HIGH_IN 是系统(芯片)主电源,这个电源会同时供给给 SNVS_HP 和 SNVS_LP。 ②、VDD_SNVS_IN 是纽扣电池供电的电源,这个电源只会供给给 SNVS_LP,保证在系统主电源 VDD_HIGH_IN 掉电以后 SNVS_LP 会继续运行。 ③、SNVS_HP 部分。 ④、SNVS_LP 部分,此部分有个 SRTC,这个就是要使用的 RTC。 SRTC 需要外界提供一个 32.768KHz 的时钟,I.MX6U-ALPHA 核心板上的 32.768KHz 的晶振就是提供这个时钟的。


3 RTC定时器寄存器

SNVS_SRTCMR[14:0]代表SRTC计数器的高15位 SNVS_SRTCLR[31:15]代表SRTC计数器的低17位 注意:是以 1970 年 1 月 1 日0点0分0秒为起点,加上经过的总秒数即可得到现在的时间点。 SNVS_HPCOMR[31], NPSWA_EN位,非特权软件访问控制位,如果非特权软件要访问 SNVS 的话此位必须为 1。 SNVS_LPCR[0], SRTC_ENV位,使能 STC 计数器。

4 RTC裸机源码展示

NXP 官方 SDK 包是针对 I.MX6ULL 编写的,因此文件 MCIMX6Y2.h中的结构体 SNVS_Type 里面的寄存器是不全的,我们需要在其中加入本章实验所需要的寄存器,修改 SNVS_Type 为如下所示:


/*!

 * @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.

文件名 :    bsp_rtc.c

作者     : 左忠凯

版本     : V1.0

描述     : RTC驱动头文件。

其他     : 无

论坛     : www.wtmembed.com

日志     : 初版V1.0 2019/1/3 左忠凯创建

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

#include 'imx6ul.h'


/* 相关宏定义 */ 

#define SECONDS_IN_A_DAY        (86400) /* 一天86400秒         */

#define SECONDS_IN_A_HOUR       (3600)  /* 一个小时3600秒        */

#define SECONDS_IN_A_MINUTE     (60)    /* 一分钟60秒           */

#define DAYS_IN_A_YEAR          (365)   /* 一年365天           */

#define YEAR_RANGE_START        (1970)  /* 开始年份1970年        */

#define YEAR_RANGE_END          (2099)  /* 结束年份2099年        */


/* 时间日期结构体 */   

struct rtc_datetime

{

    unsigned short year;  /* 范围为:1970 ~ 2099        */

    unsigned char month;  /* 范围为:1 ~ 12             */

    unsigned char day;    /* 范围为:1 ~ 31 (不同的月,天数不同).*/

    unsigned char hour;   /* 范围为:0 ~ 23             */

    unsigned char minute; /* 范围为:0 ~ 59             */

    unsigned char second; /* 范围为:0 ~ 59             */

};


/* 函数声明 */

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.

文件名 :    bsp_rtc.c

作者     : 左忠凯

版本     : V1.0

描述     : RTC驱动文件。

其他     : 无

论坛     : www.wtmembed.com

日志     : 初版V1.0 2019/1/3 左忠凯创建

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

#include 'bsp_rtc.h'

#include 'stdio.h'


/* 

 * 描述:初始化RTC

 */

void rtc_init(void)

{

    /*

     * 设置HPCOMR寄存器

     * bit[31] 1 : 允许访问SNVS寄存器,一定要置1

     * bit[8]  1 : 此位置1,需要签署NDA协议才能看到此位的详细说明,

     *             这里不置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); //初始化时间和日期

#endif


    rtc_enable();   //使能RTC


}


/*

 * 描述: 开启RTC

 */

void rtc_enable(void)

{

    /*

     * LPCR寄存器bit0置1,使能RTC

     */

    SNVS->LPCR |= 1 << 0;   

    while(!(SNVS->LPCR & 0X01));//等待使能完成


}


/*

 * 描述: 关闭RTC

 */

void rtc_disable(void)

{

    /*

     * LPCR寄存器bit0置0,关闭RTC

     */

    SNVS->LPCR &= ~(1 << 0);    

    while(SNVS->LPCR & 0X01);//等待关闭完成

}


/*

 * @description : 判断指定年份是否为闰年,闰年条件如下:

 * @param - year: 要判断的年份

 * @return      : 1 是闰年,0 不是闰年

 */

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     : 将时间转换为秒数

 * @param - datetime: 要转换日期和时间。

 * @return          : 转换后的秒数

 */

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;         /* 平年,每年365天 */

        if(rtc_isleapyear(i)) days += 1;/* 闰年多加一天       */

    }


    days += monthdays[datetime->month];

    if(rtc_isleapyear(i) && (datetime->month >= 3)) days += 1;/* 闰年,并且当前月份大于等于3月的话加一天 */


    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     : 设置时间和日期

 * @param - datetime: 要设置的日期和时间

 * @return          : 无

 */

void rtc_setdatetime(struct rtc_datetime *datetime)

{

    unsigned int seconds = 0;

    unsigned int tmp = SNVS->LPCR; 


    rtc_disable();  /* 设置寄存器HPRTCMR和HPRTCLR的时候一定要先关闭RTC */


    /* 先将时间转换为秒         */

    seconds = rtc_coverdate_to_seconds(datetime);


    SNVS->LPSRTCMR = (unsigned int)(seconds >> 17); /* 设置高16位 */

    SNVS->LPSRTCLR = (unsigned int)(seconds << 15); /* 设置地16位 */


    /* 如果此前RTC是打开的在设置完RTC时间以后需要重新打开RTC */

    if (tmp & 0x1)

        rtc_enable();

}


/*

 * @description     : 将秒数转换为时间

 * @param - seconds : 要转换的秒数

 * @param - datetime: 转换后的日期和时间

 * @return          : 无

 */

void rtc_convertseconds_to_datetime(u64 seconds, struct rtc_datetime *datetime)

{

    u64 x;

    u64  secondsRemaining, days;

    unsigned short daysInYear;


    /* 每个月的天数       */

    unsigned char daysPerMonth[] = {0U, 31U, 28U, 31U, 30U, 31U, 30U, 31U, 31U, 30U, 31U, 30U, 31U};


    secondsRemaining = seconds; /* 剩余秒数初始化 */

    days = secondsRemaining / SECONDS_IN_A_DAY + 1;         /* 根据秒数计算天数,加1是当前天数 */

[1] [2]
关键字:实时时钟 引用地址:IMX6ULL裸机-1-RTC定时器

上一篇:IMX6ULL裸机-2-PWM定时器
下一篇:s3c2440裸机-电阻触摸屏-7-触摸屏校准测试及优化

推荐阅读最新更新时间:2026-03-21 13:04

STM32CubeMX学习笔记(14)——RTC实时时钟使用
一、RTC简介 实时时钟(RTC) 是一个独立的 BCD 定时器/计数器。 RTC 提供具有可编程闹钟中断功能的日历时钟/日历。RTC 还包含具有中断功能的周期性可编程唤醒标志。两个 32 位寄存器包含二进码十进数格式 (BCD) 的秒、分钟、小时( 12 或 24 小时制)、星期几、日期、月份和年份。此外,还可提供二进制格式的亚秒值。系统可以自动将月份的天数补偿为 28、29(闰年)、30 和 31 天。只要芯片的备用电源一直供电,RTC上的时间会一直走。 STM32 的 RTC 外设(Real Time Clock),实质是一个掉电后还继续运行的定时器。从定时器的角度来说,相对于通用定时器 TIM 外设,它十分简单,只有很纯
[单片机]
STM32学习笔记之RTC实时时钟2
5. 程序实现 5.1 初始化 u8 RTC_Init(void){ u8 temp=0; RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE); //使能PWR和BKP外设时钟 PWR_BackupAccessCmd(ENABLE); //使能后备寄存器访问 if (BKP_ReadBackupRegister(BKP_DR1) != 0x5050) //从指定的后备寄存器中读出数据:读出了与写入的指定数据不相乎 { BKP_DeInit(); //复位备份区域
[单片机]
STM32学习笔记之<font color='red'>RTC</font><font color='red'>实时时钟</font>2
STM32CubeMX-实时时钟(RTC)
RTC简介 实时时钟(RTC)是一个独立的 BCD 定时器/计数器。RTC 提供具有可编程闹钟中断功能的日历时钟/日历。RTC 还包含具有中断功能的周期性可编程唤醒标志。系统可以自动将月份的天数补偿为 28、29(闰年)、30和 31 天。只要芯片的备用电源一直供电,RTC上的时间会一直走。 新建工程 本章程序在串口printf工程的基础上修改,复制串口printf的工程,修改文件夹名。点击STM32F746I.ioc打开STM32cubeMX的工程文件重新配置。RTC选择内部唤醒(Internal WakeUp)开启RTC。开启外部低速晶振,PC14,PC15配置。 RTC时钟选择为外部低速晶振(LSE),频率为32.7
[单片机]
STM32CubeMX-<font color='red'>实时时钟</font>(<font color='red'>RTC</font>)
STM32CubeMX系列 | RTC实时时钟
1. RTC实时时钟简介 STM32的实时时钟RTC是一个独立的定时器,RTC模块拥有一组连续计数的计数器,在相应软件配置下,可提供时钟日历的功能,修改计数器的值可以重新设置系统当前的时间和日期 RTC模块和时钟配置系统(RCC_BDCR寄存器)是在后背区域,即在系统复位或从待机模式唤醒后RTC的设置和事件维持不变。但是在系统复位后,会自动禁止访问后备寄存器和RTC,以防止对后备区域(BKP)的意外操作。所以在要设置时间之前,要先取消备份区域写保护。RTC的简化框图如下所示: RTC由两个主要部分组成:第一部分(APB1接口)用来和APB1总线相连,此单元还包含一组16位寄存器,可通过APB1总线对其进行读写操作;另一部分(R
[单片机]
基于51单片机的实时时钟+温度应用设计
显示实时时钟、温度检测并使用LCD1602显示相关信息 ,能模式切换、加减时间。 仿真图: 程序运行图: 部分程序: #include REG51.H #include intrins.h //#include LCD1602.h //#include DS1302.h #define uint unsigned int #define uchar unsigned char sbit DS1302_CLK = P1^7; //实时时钟时钟线引脚 sbit DS1302_IO = P1^6; //实时时钟数据线引脚 sbit DS1302_RST = P1^5; //实时时钟复位线引脚 sbit wireless_1 =
[单片机]
【51单片机快速入门指南】4.6:I2C 与 PCF8563实时时钟日历芯片
STC实验箱4 IAP15W4K58S4 Keil uVision V5.29.0.0 PK51 Prof.Developers Kit Version:9.60.0.0 硬知识 摘自《PCF8563实时时钟日历芯片选型指南》。 概述 PCF8563是低功耗的CMOS实时时钟日历芯片。它提供一个可编程时钟输出一个中断输出和掉电检测器所有的地址和数据,通过12C总线接口串行传递最大总线速度为400Kbits/s,每次读写数据后内嵌的字地址寄存器会自动产生增量。 特性 低工作电流典型值:0.25 A(VDD=3.0V T a m b T_{amb}T amb =25) 世纪标志; 大工作电压范围:
[单片机]
【51单片机快速入门指南】4.6:I2C 与 PCF8563<font color='red'>实时时钟</font>日历芯片
【STM32】HAL库-RTC实时时钟
简介 实时时钟是一个独立的定时器 RTC模块和时钟配置系统(RCC_BDCR寄存器)处于后备区域,即在系统复位或从待机模式唤醒后,RTC的设置和时间维持不变 系统复位后,对后备寄存器和RTC的访问被禁止,这是为了防止对后备区域(BKP)的意外写操作。执行以下操作将使能对后备寄存器和RTC的访问: 设置寄存器RCC_APB1ENR的PWREN和BKPEN位,使能电源和后备接口时钟 设置寄存器PWR_CR的DBP位,使能对后备寄存器和RTC的访问。 时钟源 通过设置备份域控制寄存器(RCC_BDCR)里的RTCSEL 位,RTCCLK时钟源可以由HSE/128、LSE或LSI时钟提供。 除非备份域复位,此选择不能被改变。
[单片机]
【STM32】HAL库-<font color='red'>RTC</font><font color='red'>实时时钟</font>
【C51自学笔记】实时时钟芯片DS1302
简介: 芯片内部具有可编程日历时钟和31个字节的静态RAM,日历时钟可自动进行闰年补偿,计时准确,接口简单,使用方便,工作电压范围宽,功耗低,芯片自身还具有对备份电池进行涓流充电功能,可以有效地延长备份电池的使用寿命。 连接图:8051单片机与DS1302的一种接口电路 单片机与DS1302之间采用3线串行通信方式 RST为通信允许信号,RST=1允许通信,RST=0禁止通信。 IO为双向串行数据传送信号,SCLK为串行数据的位同步脉冲信号。 8051作为主机通过控制RST、SCLK和IO信号实现两芯片之间的数据传送。 DS1302芯片的X1和X2端外接32.768KHz的石英晶振 Vcc1和Vcc2是电源引脚,单电源
[单片机]
【C51自学笔记】<font color='red'>实时时钟</font>芯片DS1302
小广播
最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

厂商技术中心

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

 
机器人开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2026 EEWORLD.com.cn, Inc. All rights reserved