实时时钟

实时时钟(RTC)是一个专用的计数器 / 定时器,可提供日历信息,包括小时、分钟、秒、日、月份、年份以及星期。RTC 具有两个独立闹钟,时间、日期可组合设定,可产生闹钟中断,并通过引脚输出;支持时间戳功能,可通过引脚触发,记录当前的日期和时间,同时产生时间戳中断;支持周期中断;支持自动唤醒功能,可产生中断并通过引脚输出;支持1Hz 方波和RTCOUT 输出功能;支持内部时钟校准补偿。

CW32L083 内置经独立校准的 32kHz 频率的 RC 时钟源,为 RTC 提供驱动时钟,RTC 可在深度休眠模式下运行, 适用于要求低功耗的应用场合。

1.png

RTC功能框图

RTC 时钟源RTCCLK 通过CR1寄存器进行选择,可选源为LSE、LSI和 HSE分频时钟。

主要功能

实时时钟 (RTC) 主要由专用的高精度 RTC 定时器组成,时钟源可选择外部低速时钟 LSE 或内部低速时钟 LSI,当选择外部高速时钟 HSE 时,因精度受限只能用作一般定时 / 计数器。 

时间寄存器 RTC_TIME 和日期寄存器 RTC_DATE,以 BCD 码格式分别记录当前的时间和日期值,在对其写入时会自动进行合法性检查,任何非法的时间或日期值将不能被写入,如 32 日、2A 时、61 秒、13 月等。

日期寄存器 RTC_DATE 中,YEAR 位域表示年,有效值 0 ~ 99;MONTH 位域表示月,有效值 1 ~ 12;DAY 位域表 示日,有效值 1 ~ 31;WEEK 位域表示星期,有效值 0 ~ 6,其中 0 表示星期日,1 ~ 6 表示星期一至星期六。

时间寄存器 RTC_TIME 中,SECOND 位域表示秒,有效值 0 ~ 59;MINUTE 位域表示分,有效值 0 ~ 59;HOUR 位域代表小时,有效值为 1 ~ 12 或 0 ~ 23;HOUR 位域的最高位代表 AM/PM(上午 / 下午):- ‘0’表示 AM - ‘1’表示 PM HOUR。控制寄存器 RTC_CR0 的 H24 位域用于选择 12 或 24 小时制:• H24 为‘1’时,选择 24 时制 • H24 为‘0’时,选择 12 时制。HOUR位域值含义详细见下表:

2.png

其他功能

1.闹钟 A 和闹钟 B 

RTC 支持 2 个独立闹钟(闹钟 A 和闹钟 B),可在一周内任意时刻产生闹钟事件,并产生闹钟中断,同时将闹钟匹配事件通过外部 RTC_OUT 引脚输出。设置控制寄存器 RTC_CR2 的 ALARMAEN 和 ALARMBEN 位域为 1,可分别单独使能闹钟 A 和闹钟 B。通过设置闹钟 A、B 控制寄存器(RTC_ALARMA 和 RTC_ALARMB)的时、分、秒匹配控制位 HOUREN、 MINUTEEN、SECONDEN 和时、分、秒计数值 HOUR、MINUTE、SECOND,可设定闹钟在‘xx 时 xx 分 xx 秒’, 或‘xx 分 xx 秒’或‘xx 时 xx 分’或‘xx 时’等多种组合产生闹钟事件;闹钟星期使能控制位 WEEKMASK,可选择一周中的任意一天产生闹钟事件,bit0 代表星期日,bit1 ~ 6 代表星期一至星期六。采用 12 或 24 小时制,闹钟控制寄存器 RTC_ALARMx(x = A, B) 的设置值可能不同,示例如下表:

3.png

2.周期中断功能:RTC 内置周期中断模块,可产生固定周期的中断信号。

3.自动唤醒功能

自动唤醒定时器是一个 16 位可编程自动重载减法计数器,计数时钟源为RTCCLK或者RTC1HZ时钟。定时范围为:61μs ~ 145h。当计数器溢出时,可产生自动唤醒中断,并将溢出标志通过 RTC_OUT 引脚输出。设置控制寄存器 RTC_CR2 的 AWTEN 位域为 1 使能自动唤醒功能,该功能专为低功耗应用场合而设计,可工作于 MCU 的全部工作模式。

自动唤醒定时器计数周期由计数时钟源和重载寄存器 RTC_AWTARR 决定,定时时长计算公式为:自动唤醒定时器定时周期 =(RTC_AWTARR+1)/ 唤醒定时器计数时钟频率 最短定时:( 0+1 ) / 16384Hz = 61μs 最长定时:(65535+1) / 0.125Hz = 524288s = 8738min ≈ 145.63h 通过 RTC 中断使能寄存器 RTC_IER 的 AWTIMER 位域,可选择自动唤醒定时器溢出时是否产生中断请求。

4.时间戳功能 

RTC 支持时间戳功能,即通过 RTC_TAMP 引脚触发,将当前时间和日期分别保存到时间戳日期寄存器 RTC_TAMPDATE 和时间戳时间寄存器 RTC_TAMPTIM,同时可产生时间戳中断。控制寄存器 RTC_CR2 的 TAMPEDGE 位域用来选择触发时间戳的信号是上升沿还是下降沿有效,RTC_CR2 寄存 器的 TAMPEN 位域用于使能时间戳功能。用户可灵活选择触发引脚 RTC_TAMP,并需配置该引脚为数字输入和复用功能,具体 RTC_TAMP 引脚请参考数据手册引脚定义。当发生时间戳事件时,时间戳事件标志位 RTC_ISR.TAMP 会被置 1,如果设置了时间戳中断使能位 RTC_IER.TAMP 为 1,将产生中断请求。如果发生第一次时间戳事件后,未通过软件清除 RTC_ISR.TAMP 标志位,又产生了第二次时间戳事件,时间戳溢出标志位 RTC_ISR.TAMPOV 会被置 1,如果设置了时间戳溢出中断使能位 RTC_IER.TAMPOV 为 1,将产生中断请求。

实际例程操作——RTC初始化,日期时间读取,间隔中断,闹钟设置

1.系统时钟初始化设置

void RCC_Configuration(void)
{
    RCC_HSI_Enable(RCC_HSIOSC_DIV6);   //设置系统时钟为8M
    RCC_LSE_Enable(RCC_LSE_MODE_OSC, RCC_LSE_AMP_NORMAL, RCC_LSE_DRIVER_NORMAL); 
    // 打开LSE时钟,作为RTC的计数时钟
    RCC_APBPeriphClk_Enable1(RCC_APB1_PERIPH_RTC, ENABLE);  //打开RTC模块工作时钟
}

2.配置输出时间所需GPIO口以及串口UART配置

void LogInit(void)
{
        SerialInit(LOG_SERIAL_BPS);
}
static void SerialInit(uint32_t BaudRate)
{
    uint32_t PCLK_Freq;
    GPIO_InitTypeDef GPIO_InitStructure = {0};
    UART_InitTypeDef UART_InitStructure = {0};
    PCLK_Freq = SystemCoreClock >> pow2_table[CW_SYSCTRL->CR0_f.HCLKPRS];
    PCLK_Freq >>= pow2_table[CW_SYSCTRL->CR0_f.PCLKPRS];
    // 调试串口使用UART5//    PB8->TX//  PB9<-RX// 时钟使能
    __RCC_GPIOB_CLK_ENABLE();
    __RCC_UART5_CLK_ENABLE();
    // 先设置UART TX RX 复用,后设置GPIO的属性,避免口线上出现毛刺
    PB08_AFx_UART5TXD();
    PB09_AFx_UART5RXD();
    PIO_InitStructure.Pins = GPIO_PIN_8;
    GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
    GPIO_Init(CW_GPIOB, &GPIO_InitStructure);
    GPIO_InitStructure.Pins = GPIO_PIN_9;
    GPIO_InitStructure.Mode = GPIO_MODE_INPUT;
    GPIO_Init(CW_GPIOB, &GPIO_InitStructure);

    UART_InitStructure.UART_BaudRate = BaudRate;// 波特率
    UART_InitStructure.UART_Over = UART_Over_16;// 采样方式
    UART_InitStructure.UART_Source = UART_Source_PCLK;// 传输时钟源UCLK
    UART_InitStructure.UART_UclkFreq = PCLK_Freq;// 传输时钟UCLK频率
    UART_InitStructure.UART_StartBit = UART_StartBit_FE;// 起始位判定方式
    UART_InitStructure.UART_StopBits = UART_StopBits_1;// 停止位长度
    UART_InitStructure.UART_Parity = UART_Parity_No;// 校验方式
    UART_InitStructure.UART_HardwareFlowControl = UART_HardwareFlowControl_None;
    //硬件流控
    UART_InitStructure.UART_Mode = UART_Mode_Rx | UART_Mode_Tx; // 发送/接收使能
    UART_Init(CW_UART5, &UART_InitStructure);
}

3.设置输出时间日期格式

void ShowTime(void)
{

    RTC_TimeTypeDef RTC_TimeStruct = {0};
    RTC_DateTypeDef RTC_DateStruct = {0};
    static uint8_t *WeekdayStr[7]= {"SUN","MON","TUE","WED","THU","FRI","SAT"};
    static uint8_t *H12AMPMStr[2][2]= {{"AM","PM"},{"",""}};

    RTC_GetDate(&RTC_DateStruct);// 取用当前日期,BCD格式
    RTC_GetTime(&RTC_TimeStruct);// 获取当前时间,BCD格式
    printf(".Date is 20%02x/%02x/%02x(%s).Time is %02x%s:%02x:%02x\r\n", 
    RTC_DateStruct.Year, RTC_DateStruct.Month, RTC_DateStruct.Day, 
    WeekdayStr[RTC_DateStruct.Week], RTC_TimeStruct.Hour, 
    H12AMPMStr[RTC_TimeStruct.H24][RTC_TimeStruct.AMPM],RTC_TimeStruct.Minute, 
    RTC_TimeStruct.Second);//串口打印数据
}

Void RTC_GetDate(RTC_DateTypeDef* RTC_Date)
{

    uint32_t RegTmp = 0;

    RegTmp = CW_RTC->DATE;
    while (RegTmp != CW_RTC->DATE)
    {

      RegTmp = CW_RTC->DATE;    // 连续两次读取的内容一致,认为读取成功

    }

    RTC_Date->Day = (uint8_t)(RegTmp & RTC_DATE_DAY_Msk);
    RTC_Date->Month = (uint8_t)((RegTmp & RTC_DATE_MONTH_Msk) >> 8);
    RTC_Date->Year = (uint8_t)((RegTmp & RTC_DATE_YEAR_Msk) >> 16);
    RTC_Date->Week = (uint8_t)((RegTmp & RTC_DATE_WEEK_Msk) >> 24);
}

Void RTC_GetTime(RTC_TimeTypeDef* RTC_TimeStruct)
{

    uint32_t RegTmp = 0;
    RTC_TimeStruct->H24 = CW_RTC->CR0_f.H24;  // 读CR0是否需要连读两次,待硬件检测
    RegTmp = CW_RTC->TIME;
    while (RegTmp != CW_RTC->TIME)
    {
      RegTmp = CW_RTC->TIME;    // 连续两次读取的内容一致,认为读取成功
    }

    RTC_TimeStruct->Hour = (uint8_t)((RegTmp & RTC_TIME_HOUR_Msk) >> 16);
    RTC_TimeStruct->Minute = (uint8_t)((RegTmp & RTC_TIME_MINUTE_Msk) >> 8);
    RTC_TimeStruct->Second = (uint8_t)(RegTmp & RTC_TIME_SECOND_Msk);
    if (RTC_TimeStruct->H24 == RTC_HOUR12)

    {
      RTC_TimeStruct->AMPM = RTC_TimeStruct->Hour >> 5;
      RTC_TimeStruct->Hour &= 0x1f;
    }
}

4.RTC模块初始化,ErrorStatus 返回值为SUCCESS或ERROR

ErrorStatus RTC_Init(RTC_InitTypeDef* RTC_InitStruct)
{

     CW_SYSCTRL->APBEN1_f.RTC = 1;            //  启动RTC外设时钟,使能RTC模块

     if ((RCC_GetAllRstFlag() & SYSCTRL_RESETFLAG_POR_Msk) != RCC_FLAG_PORRST)  
      //不是上电复位,直接退出

     { 
       RCC_ClearRstFlag(RCC_FLAG_ALLRST);        
          return SUCCESS; 
      }

     RTC_Cmd(DISABLE);                        //  停止RTC,保证正确访问RTC寄存器

     RTC_SetClockSource(RTC_InitStruct->RTC_ClockSource);        // 设置RTC时钟源, 用户需首先启动RTC时钟源!!!
     RTC_SetDate(&RTC_InitStruct->DateStruct);// 设置日期,DAY、MONTH、YEAR必须为BCD方,星期为0~6,代表星期日,星期一至星期六
     RTC_SetTime(&RTC_InitStruct->TimeStruct); //时间,HOUR、MINIUTE、SECOND必须为BCD方式,用户须保证HOUR、AMPM、H24之间的关联正确性
     RTC_Cmd(ENABLE);
     RCC_ClearRstFlag(RCC_FLAG_ALLRST);  
     return SUCCESS;
}

5.RTC周期中断时间设置

int RTC_SetInterval(uint8_t Period)
{

    uint16_t timeout = 0xffff;
    RTC_UNLOCK();
    if (IS_RTC_START())         // 如果RTC正在运行,则使用WINDOWS、ACCESS访问
    {

      CW_RTC->CR1_f.ACCESS = 1; 
      while ((!CW_RTC->CR1_f.WINDOW) && timeout--);
      if (timeout == 0) return 1;
     }
     CW_RTC->CR0_f.INTERVAL = Period;
     CW_RTC->CR1_f.ACCESS = 0;
     RTC_LOCK();
     return 0;
}

6.设置时钟中断使能

int RTC_ITConfig(uint32_t RTC_IT, FunctionalState NewState)
{

    uint16_t timeout = 0xffff;
    RTC_UNLOCK();
    CW_RTC->CR1_f.ACCESS = 1;
    while ((!CW_RTC->CR1_f.WINDOW) && timeout--);
    if (timeout == 0) return 1;
    if (!NewState)
    {
      CW_RTC->IER &= ~RTC_IT;
    }
    else
    {
      CW_RTC->IER |= RTC_IT;
    }

    CW_RTC->CR1_f.ACCESS = 0;
    RTC_LOCK();
    return 0;
}

void RTC_IRQHandlerCallBack(void)
{

    if (RTC_GetITState(RTC_IT_ALARMA))
    {
      RTC_ClearITPendingBit(RTC_IT_ALARMA);
      printf("*********Alarm!!!!\r\n");

    }
    if (RTC_GetITState(RTC_IT_INTERVAL))
    {
      RTC_ClearITPendingBit(RTC_IT_INTERVAL);
      ShowTime();
    }
 
void NVIC_Configuration(void)
{
      __disable_irq();
      NVIC_EnableIRQ(RTC_IRQn);
      __enable_irq();
}

7.RTC时钟测试,初始化日历,使用间隔中断0.5秒通过Log输出日期时间

int32_t main(void)
{

    RTC_InitTypeDef RTC_InitStruct = {0};
    RTC_AlarmTypeDef RTC_AlarmStruct = {0};
    /*系统时钟配置*/
    RCC_Configuration();
    /* GPIO 口配置*/
    GPIO_Configuration();
    LogInit();//配置输出时间所需GPIO口以及串口UART配置
    printf("RTC Init...\r\n");
    printf(" (RTC CR0:%04x,CR1:%04x,CR2:%04x,RESET FLAG:0x%08x)\r\n",CW_RTC-
    >CR0,CW_RTC->CR1,CW_RTC->CR2,CW_SYSCTRL->RESETFLAG);
    RCC_LSE_Enable(RCC_LSE_MODE_OSC, RCC_LSE_AMP_NORMAL, RCC_LSE_DRIVER_NORMAL);  // 选择LSE为RTC时钟
    RTC_InitStruct.DateStruct.Day = 0x21;             //日
    RTC_InitStruct.DateStruct.Month = RTC_Month_June;//月
    RTC_InitStruct.DateStruct.Week = RTC_Weekday_Monday;//星期
    RTC_InitStruct.DateStruct.Year = 0x21; //年
    //设置日期,DAY、MONTH、YEAR必须为BCD方式,星期为0~6,代表星期日,星期一至星期六
    printf("-------Set Date as 20%x/%x/%x\r\n", RTC_InitStruct.DateStruct.Year,RTC_InitStruct.DateStruct.Month,RTC_InitStruct.DateStruct.Day);
    //打印日期
    RTC_InitStruct.TimeStruct.Hour = 0x11;   //时    
    RTC_InitStruct.TimeStruct.Minute = 0x58;//分
    RTC_InitStruct.TimeStruct.Second = 0x59;//秒
    RTC_InitStruct.TimeStruct.AMPM = 0;
    RTC_InitStruct.TimeStruct.H24 = 0; //采用12小时设置
    //设置时间,HOUR、MINIUTE、SECOND必须为BCD方式,用户须保证HOUR、AMPM、H24之间的关联正确性
    printf("-------Set Time as %02x:%02x:%02x\r\n", RTC_InitStruct.TimeStruct.Hour,RTC_InitStruct.TimeStruct.Minute,RTC_InitStruct.TimeStruct.Second);//打印时间
    RTC_InitStruct.RTC_ClockSource = RTC_RTCCLK_FROM_LSE;
    RTC_Init(&RTC_InitStruct);    // RTC模块初始化, 用户需选定需要使用的时钟源
    printf("=====Set interval period as 0.5s...\r\n");
    RTC_SetInterval(RTC_INTERVAL_EVERY_0_5S);
    //闹钟为工作日上午的6:45
    RTC_AlarmStruct.RTC_AlarmMask = RTC_AlarmMask_WeekMON | RTC_AlarmMask_WeekTUE |
    RTC_AlarmMask_WeekWED | RTC_AlarmMask_WeekTHU |RTC_AlarmMask_WeekFRI;
    //设定时间为周一到周五
    RTC_AlarmStruct.RTC_AlarmTime.Hour = 6;
    RTC_AlarmStruct.RTC_AlarmTime.Minute = 0x45;
    RTC_AlarmStruct.RTC_AlarmTime.Second = 0;
    RTC_SetAlarm(RTC_Alarm_A, &RTC_AlarmStruct);   // 设置闹钟,BCD格式
    RTC_AlarmCmd(RTC_Alarm_A, ENABLE);//使能闹钟
    printf("=====Enable ALRAMA and INTERVAL IT...\r\n");
    RTC_ITConfig(RTC_IT_ALARMA | RTC_IT_INTERVAL, ENABLE);
    //设置中断使能
    While(1){}
}

8.通过UART串口验证RTC工作正常

4.png

以上是CW32L083单片机的RTC设置时间及闹钟部分的介绍,CW32其他型号亦可参考此篇文档。有关芯片购买事宜,请咨询武汉芯源的销售和官方代理商。更多MCU详细信息,请访问武汉芯源官方网站:https://www.whxy.com

来源:武汉芯源半导体

免责声明:本文为转载文章,转载此文目的在于传递更多信息,版权归原作者所有。本文所用视频、图片、文字如涉及作品版权问题,请联系小编进行处理(联系邮箱:cathy@eetrend.com)。

围观 38

MICRO CRYSTAL新型RV-3032-C7高性能温度补偿实时时钟模块,带I2C接口。

微晶推出全新的RV-3032-C7实时时钟(RTC)模块,以超低的电流消耗,在工业温度范围内提供全球最佳的时间精度。


这款高性能的超小型RTC模块,采用定制的IC和集成的石英晶体谐振器,在最小的尺寸(只有uSOP-8封装的一半,不需要额外的外部元件)、最佳的精度(在-40°至85°C的工作温度下,±0.26秒/天)、超低的电流消耗(160 nA的计时模式)和独特的电源管理能力方面树立了新的标准。

RV-3032-C7是需要始终在线计时功能的应用的理想选择,符合严格的时钟精度随时间变化、宽广的温度范围和较长的电池寿命。它的设计考虑到了智能计量和其他类似的工业或消费应用,如可穿戴设备和物联网。

由于其极低的功耗和电源管理功能,包括宽电源电压范围(1.2至5.5 V)、自动备份开关、多功能充电泵和可编程涓流充电器,该器件可与小尺寸、低容量、可充电电池或低成本的纽扣电池电源单元相连接。这样可以降低终端产品的整体尺寸和制造成本,同时优化电池的使用寿命。

"新的RV-3032-C7实时时钟模块,包括我们最先进的基于石英的DTCXO[1],是微晶产品线中最具创新性、最能树立基准的器件。RV-3032-C7在跨温度、低功耗和最小封装的精度方面设立了新的世界标准。设计团队运用了他们40年的频率控制专业技术,开发了一个令人印象深刻的组件,并对客户的要求进行了彻底的分析和定义,以开发和生产出这一最佳器件。除了所有标准RTC的功能外,它还包括多种额外的功能,如通过密码进行数据保护,以及MHz输出频率,现在在市场上首次在如此微小的器件中提供,"Micro Crystal AG的首席执行官Hans-Rudolf Gottier说。

"RV-3032-C7 RTC为与精度、电源、尺寸和电池寿命有关的关键设计限制提供了解决方案,必将有助于工程师开发下一代智能产品。微晶股份公司应用工程主管Roland Haeni表示,提供可编程的高频时钟输出以驱动中央MCU,并可访问高分辨率的温度计,用于精确的热补偿,并允许设置带有中断功能的温度阈值报警,将支持众多独特的新应用。

该产品采用紧凑的可回流焊DFN[2]陶瓷封装,尺寸为3.2 x 1.5 x 0.8 mm,符合RoHS/无铅标准,并通过AEC-Q200认证,便于新的设计。

更多信息和可用性

RV-3032-C7 RTC模块现已开始提供样品。大批量生产将于2021年第一季度开始。样品和演示板可以从主页上订购。
网站链接:
https://www.microcrystal.com/en/products/real-time-clock-rtc/rv-3032-c7/

关于公司

瑞士斯沃琪集团旗下的Micro Crystal AG公司是一家基于32.768 kHz计时设备的领先制造商。
Micro Crystal总部位于瑞士Grenchen,在石英晶体解决方案的设计、制造和销售方面拥有40多年的经验。

我们的产品组合包括晶体、振荡器、OCXO和实时时钟模块,为全球领先的物联网、可穿戴设备、血糖仪、消费产品、GPS模块、汽车电子和医疗保健产品制造商提供服务。Micro Crystal也是医疗植入式应用的计时设备的领先供应商,包括心脏起搏器、除颤器和神经调节器,以及其他高可靠性应用的产品。我们在瑞士和泰国设有生产基地,并在欧洲、美国和亚洲设有众多的销售和技术支持办事处,从早期的设计活动到大规模生产,我们都与全球客户保持着紧密的合作。Micro Crystal代表着领先的技术、可靠性和高质量、环保的生产过程。

www.microcrystal.com

围观 64

MAX31341B工作电流低于180nA,有效延长可穿戴设备、零售终端及便携系统的电池寿命

Maxim Integrated Products, Inc (NASDAQ: MXIM)宣布推出MAX31341B nanoPower实时时钟 (RTC),在可穿戴设备、医用监测仪、零售终端(POS)设备和便携式终端等空间受限系统设计中有效延长电池寿命、节省功耗及空间。与当今市场上最小的RTC方案相比,该nanoPower RTC体积缩减35%以上,工作耗流不足180nA,有效减轻中央微控制器的计时负担,在休眠期间大幅节省功耗、延长电池运行时间。

采用微控制器实现精确计时的系统会消耗大量的电池能量,这在可穿戴应用中是不可接受的。这种方法不是有效的解决方案,特别是对于小型电池供电系统。MAX31341B采用业界领先的电源管理电路,该电路在休眠期间保持计时功能,可以关断微控制器,从而节省功耗、延长电池寿命。RTC采用2mm x 1.5mm晶圆级封装,尺寸缩小35%以上,并有助于缩短系统开发时间。

主要优势

  • 长电池寿命:与最接近的竞争产品相比,工作电流降低18%,不足180nA,MAX31341B的计时电流允许在标准纽扣锂电池供电模式下持续工作10小时以上。
  • 小尺寸方案:器件通过集成负载电容、涓流充电器、电源管理和64字节RAM等,最大程度减少外部电路
  • 精确计时:在-40°C至+85°C温度范围内,计时精度达到100ppm (百万分之一) (基于外部晶振)。

评价

  • “延长系统电池寿命一直是小型化电子设备开发人员不断面临的挑战,任何通过提高电路工作效率来延长电池寿命的方案都会成为下一代系统的关注焦点。”IHS Markit资深分析师Kevin Anderson表示。
  • “Maxim的实时时钟可提供精确的计时功能,并有效延长电池寿命、节省能耗,非常适合需要始终保持运行、空间及功耗受限的应用。”Maxim Integrated核心产品事业部业务管理总监Binay Bajaj表示:“作为业界唯一具有电源管理功能的RTC,该器件可以减轻应用处理器的计时负荷,并且在设备关闭时保持有效计时。”

供货及价格

  • MAX31341B的价格为0.70美元 (1000片起,美国离岸价),可通过Maxim官网及特许经销商购买
  • 提供MAX31341BEVKIT# 评估套件,价格为100美元
围观 144

一、什么是RTC

实时时钟(Real_Time Clock)简称为RTC,主要为各种电子系统提供时间基准。通常把集成于芯片内部的RTC称为片内RTC,在芯片外扩展的RTC称为外部RTC。

如何正确设计实时时钟RTC?
图1 时间格式

二、 RTC的发展

1、早期RTC

早期RTC常使用74/54系列、CC4000系列及555集成电路构建秒脉冲源,再利用分频器、计数器、缓存器等得到分、时、日、月、年的计时信号,最后通过通信口送到处理器处理。由于电路搭建复杂且受器件特性影响较大,这样的RTC往往精度差、功耗大且占用大面积PCB空间,且这类产品面临“2000年”的问题(千年虫问题详见百度)。

如何正确设计实时时钟RTC?
图2 千年虫问题

2、中期RTC

这一时期的RTC出现在20世纪90年代,由于采用特殊CMOS工艺,因此功耗大为降低,典型值约0.5μA以下,供电电压仅为1.4V以下。为节约宝贵的IO接口,通讯口也变为串行方式,出现了诸如三线SIO/四线SPI,部分产品采用2线I2C总线。封装上采用SOP/SSOP封装,体积大为缩小。得益于半导体技术的发展,这时的RTC精度、功耗等特性上得到实质性提高,已具备万年历功能甚至可以做到晶振停振自动检测功能。目前这类RTC正被广泛使用。

如何正确设计实时时钟RTC?
图3 PCF8583

3、新一代RTC

最新一代RTC产品中,除了包含第二代产品所具有的全部功能,更加入了复合功能,如低电压检测,主备用电池切换功能,抗印制板漏电功能,且本身封装更小(高度0.85mm,面积仅为2mm*2mm)。

三、RTC使用

RTC设计推荐方案如图4所示,若采用I2C/SPI通信的RTC IC且已具备I2C/SPI驱动程序,RTC的使用就显得尤为简单,仅需要加上晶振电路就可以工作了。

如何正确设计实时时钟RTC?
图4 RTC硬件电路

RTC设计电路简约而不简单,时钟芯片的选择、电路设计、器件放置、阻抗控制、PCB走线规范均会影响RTC的时间基准的稳定性,如图5所示为致远电子基于Cortex-A7架构的800MHz主频的M6Y2C-256F256LI-T核心板以及配套硬件开发指南,致远电子每一款核心板均有提供标准的推荐电路,为设计者提供稳定可靠的设计参考。

如何正确设计实时时钟RTC?
图5 提供完善硬件支持的核心板

软件方面,我们仅以linux为例了解下RTC的使用。在内核配置中选择与硬件匹配的RTC驱动,以生成正确的内核镜像。

如何正确设计实时时钟RTC?
图6 启用PCF8563 RTC驱动

如何正确设计实时时钟RTC?
图7 启用片内RTC

然后结合硬件测试RTC功能,使用命令date –-help获取相关指令。hwclock –w命令将设置的时间同步到硬件,hwclock命令获取RTC时间,判断是否同步成功。

如何正确设计实时时钟RTC?
图8 date命令(部分)

如何正确设计实时时钟RTC?
图9 验证保存状态

四、RTC问题

1、计时不准

RTC的主要职责就是提供准确的时间基准,计时不准的RTC毫无价值可言。目前部分MCU在片内已集成RTC,实际测试中在电池供电6小时环境下片内RTC的偏差在1-2分钟。因此,若对实时时钟有较高的要求则需优先考虑外扩RTC,若能支持温度自动补偿则精度更佳,如DS3231、PCF2129可以在后备电池供电时根据温度变化自动修改补偿量。

如何正确设计实时时钟RTC?
图10 常见RTC精度对比(供参考)

2、无法读写

RTC无法读写(通信)时可从软、硬件两方面考虑。软件方面重点考虑通信驱动的问题,在嵌入式linux系统中常表现出RTC驱动无法检测到RTC的存在。比如在启动信息中打印pcf8563_get_datetime: read error,或者无法对I2C/SPI操作。这类问题可以使用带协议解码的示波器排查、验证。

如何正确设计实时时钟RTC?
图11 I2C协议解码

硬件方面,以常用的I2C为例,最不可忽视的则是上拉电阻的使用。I2C上拉电阻选择1K-10K为宜,可根据通信速率、长度、节点数而定。在节点数多、干扰大时还应在SDA、SCL线上串联100~200ohm左右的电阻,有效抑制干扰脉冲。另外,所有IC都有意外损坏的可能,必要时更换RTC芯片。

如何正确设计实时时钟RTC?
图12 I2C上拉电阻使用

3、掉电不保存

这种情况最可能的原因是未使用备用电源或备用电源没电了,应检查硬件电源电路。软件方面可能在用户程序、自启动脚本中设置了RTC,每次重启则将RTC恢复为默认值,这时应从启动打印信息或系统日志中排查。

转自: ZLG致远电子

围观 285

介绍了一个简单的可调实时时钟系统的设计。设计中采用了Atmel32位的ARM微处理器作为控制驱动器件,实现了对DS1307实时时钟芯片的时间信息采样和液晶显示,并通过键盘来调节时间信息。通过实际的测试,该模块得到稳定的运行。

实时日历时钟在测控系统和智能显示中得到了广泛的应用。通过软件编程和CPU中断构造软时钟是一种较为常用的方法,时钟计时无需外围硬件支持,但是此种方法的弊端是计时精度会受到CPU主晶振、起振电容以及掉电的影响,而导致计时精度不高。因此采用硬件设计实时时钟是一种更为可靠的方式。

DS1307是I2C接口的8引脚实时时钟芯片,片内含有8个特殊功能寄存器和56bit的SRAM。它是一款按BCD码存取、低功耗的时钟/日历芯片,已被应用到人造板尺寸检测以及电控单元中。

1、硬件设计

设计的可调实时时钟系统原理框图如图1所示。采用了Atmel32位ARMRISC处理器中的一员,即AT91SAM7S256微处理器来驱动DS1307时钟芯片和液晶模块,并接收键盘中断来实现时间可调的功能。

基于ARM和DS1307的实时时钟系统设计

1.1 芯片与单片机的接口与连线

若要驱动DS1307芯片,一种方式是使用I2C总线虚拟技术,另一种是采用带I2C接口的单片机。AT91SAM7S256微处理器外围电路中具有两线接口(TWI),它与I2C接口相互兼容,很适合典型的处理器应用,因此系统中采用了此接口实现芯片与CPU的通信。

基于ARM和DS1307的实时时钟系统设计

DS1307使用到了32768Hz的晶振,BAT1为电池电源。I2C总线内部是双向传输电路,端口输出为开漏结构,因此接入了上拉电阻。SQW/OUT端是方波输出端,通常情况下该引脚接到能产生电平变化中断请求的输入口。

1.2 液晶显示电路

与传统的数码管相比,液晶显示具有功耗低、体积小、显示内容丰富、人机交互性好等优点。设计中使用到了的LM256160点阵液晶显示模块。利用该模块灵活的接口方式和简单方便的操作指令,可为用户提供良好的日期、时间显示和调节界面。

1.3 按键调节电路

为实现时间的可调,系统中设计了键盘输入电路。键盘包括调节模式进入键、“0~9”的数字输入键、清除键以及确认键。用户按下调节模式进入键便可以开始进行时间的设置和调节,如输入“20150920151000”代表设置时间为2015年9月20日15时10分0秒,再按下确认键便将数据信息写入到DS1307芯片中进行计数。

2、软件设计

系统的软件设计主要包括了主程序、DS1307驱动模块,液晶驱动模块、键盘中断处理模块四大部分,程序流程如图3所示。主程序中首先完成外设时钟的使能、I/O口的使能、TWI口的使能以及液晶的初始化。初始化工作完成后,处理器通过TWI接口读取DS1307中的时钟信息,数据通过液晶进行显示。当接收到外部按键中断请求时,处理器进行相应的键值中断响应,将设置好的数据写入到DS1307芯片中并返回。

基于ARM和DS1307的实时时钟系统设计

DS1307在TWI总线上是从器件,地址(SLA)固定为“11010000”,时钟信息(年、月、日、星期、时、分、秒)分别放在地址为06H~00H的时间相关寄存器中。芯片的读写主要使用到了TWI口低层驱动函数中的intAT91F_TWI_ReadByte(constAT91PS_TWIpTwi,intmode,inTInt_address,char觹data2read,intnb)和intAT91F_TWI_WriteByte(constAT91PS_TWIpTwi,intmode,inTInt_address,char觹data2send,intnb)。读写函数使用到了四个入口参数,constAT91PS_TWIpTwi是设置TWI口的基地址,intmode为主机模式,inTInt_address为器件寄存器的地址,char觹data2read是待写入数据或待读取存放的地址,intnb为写入或读取的字节数。需要注意一点是,数据是以BCD码存取的,因此在读取或写入之前需要十进制到BCD码的相互转换处理。

3、运行结果

系统的运行效果以液晶屏显示效果为准,如图4与图5所示。图4为设置时钟信息界面,设置完毕按回车键时钟开始计时,并跳转到运行显示界面。图5为设置好初始时间为2015年9月20日15时10分0秒后,时钟运行了15分38秒的显示效果。

基于ARM和DS1307的实时时钟系统设计

4、结束语

设计的可调实时时钟系统避免了系统掉电与晶振电路的影响,芯片的驱动通过采用ARM系列微处理器中TWI接口并调用相关的低层驱动程序,减少了采用总线虚拟技术的程序量。经过实际的调试,系统得到了预期的结果。该实时时钟可用于系统主界面的日期与时间显示,并为以时间为单位的事务处理提供时间基准。

转自: elecfans.com

围观 231
订阅 RSS - 实时时钟