This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] TM4C1294NCPDT:RTC 计数器将在系统复位后复位。

Guru**** 2039500 points
Other Parts Discussed in Thread: EK-TM4C1294XL
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/862126/tm4c1294ncpdt-the-rtc-counter-would-be-reset-after-system-reset

器件型号:TM4C1294NCPDT
Thread 中讨论的其他器件:EK-TM4C1294XL

大家好、TI 团队、

我使用 TI EK-TM4C1294XL 板进行 RTC 实验、我启用 RTC、如下所示:

HibernateEnableExpClk (0);

HibernateRTCEnable();

休眠计数器模式(HIBERNATE_COUNTER_24HR);

我通过 UART 用秒打印 RTC 时间、时间从"F0C3F000"开始计数。

然后我按下复位按钮来复位系统、 RTC 时间将被复位为"F0C3F000"、但我希望它继续计数。

我想知道系统复位后 RTC 时间是否可以继续计数? 如何配置 RTC?

我期待你的答复。

此致、

Eric

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    首先、我建议您将 TivaWare 库升级到当前版本2.1.4.178。

    是的、除非 Vdd 和 Vbat 都被移除、否则 RTC 可以继续跟踪时间。 TivaWare 中的简单示例未能检查休眠模块是否已启用并重新初始化休眠模块。 像这样更改 main()可以避免重新初始化休眠模块:

    int
    main (void)
    {
    bool bUpdate;
    uint32_t ui32SysClock、ui32Status、ui32HibernateCount、ui32Len;
    int32_t i32CmdStatus;
    
    //
    //从 PLL 以120MHz 运行。
    //
    ui32SysClock = MAP_SysCtlClockFreqSet ((SYSCTL_XTAL_25MHz |
    SYSCTL_OSC_MAIN |
    SYSCTL_USE_PLL |
    SYSCTL_CFG_VCO_480)、120000000);
    
    //
    //配置器件引脚。
    //
    PinoutSet (false、false);
    
    //
    //启用 UART0
    //
    ROM_SysCtlPeripheralEnable (SYSCTL_Periph_UART0);
    
    //
    //初始化控制台 I/O 的 UART
    //
    UARTStdioConfig (0、115200、ui32SysClock);
    
    //
    //启用休眠模块。
    //
    SysCtlPeripheralEnable (SYSCTL_Periph_HIBERNATE);
    
    //
    //在使用这些变量之前初始化它们。
    //
    ui32Status = 0;
    ui32休眠计数= 0;
    
    //
    //检查休眠模块是否已激活,这可能意味着
    //处理器从休眠状态中唤醒。
    //
    if (HibernateIsActivate())
    {
    //
    //读取状态位以查看导致唤醒的原因。 清除唤醒
    //源、以便器件可以再次进入休眠模式。
    //
    ui32Status = HibernateIntStatus (0);
    HibernateIntClear (ui32状态);
    
    //
    //将唤醒信息消息的公共部分存储到缓冲区中。
    //将根据状态位附加唤醒源。
    //
    ui32Len = usnprintf (g_pcWakeBuf、sizeof (g_pcWakeBuf)、
    "因以下原因而唤醒:");
    
    //
    //唤醒是由于 RTC 匹配所致。
    //
    if (ui32Status 和 HIBERNATE_INT_RTC_MATH_0)
    {
    ui32Len = usnprintf (&g_pcWakeBuf[ui32Len]、
    sizeof (g_pcWakeBuf)- ui32Len、"%s"、
    G_ppcWakeSource[0]);
    }
    
    //
    //唤醒是由于重置按钮所致。
    //
    否则、如果(ui32Status 和 HIBERNATE_INT_RESET_WAKE)
    {
    ui32Len = usnprintf (&g_pcWakeBuf[ui32Len]、
    sizeof (g_pcWakeBuf)- ui32Len、"%s"、
    G_ppcWakeSource[1]);
    }
    
    //
    //唤醒是由外部唤醒引脚引起的。
    //
    否则、如果(ui32Status 和 HIBERNATE_INT_PIN_WAKE)
    {
    ui32Len = usnprintf (&g_pcWakeBuf[ui32Len]、
    sizeof (g_pcWakeBuf)- ui32Len、"%s"、
    G_ppcWakeSource[2]);
    }
    
    //
    //唤醒是由于 GPIO 唤醒。
    //
    否则、如果(ui32Status 和 HIBERNATE_INT_GPIO_WAKE)
    {
    ui32Len = usnprintf (&g_pcWakeBuf[ui32Len]、
    sizeof (g_pcWakeBuf)- ui32Len、"%s"、
    G_ppcWakeSource[3]);
    }
    
    //
    //如果唤醒是由于任何配置的唤醒源导致的,则读取
    //从电池供电内存中的第一个位置,如所示
    //休眠计数。
    //
    if (ui32Status &(HIBERNATE_INT_PIN_WAKE | HIBERNATE_INT_RTC_MATH_0 |
    HIBERNATE_INT_GPIO_WAKE | HIBERNATE_INT_RESET_WAKE)
    {
    HibernateDataGet (\ui32 HibernateCount、1);
    }
    }
    其他
    {
    //
    //配置休眠模块时钟。
    //
    HibernateEnableExpClk (ui32SysClock);
    
    //
    //如果唤醒不是由于上述原因,则是一个系统
    //复位。
    //
    if (!(ui32Status &(HIBERNATE_INT_PIN_WAKE | HIBERNATE_INT_RTC_MATH_0 |
    HIBERNATE_INT_GPIO_WAKE | HIBERNATE_INT_RESET_WAKE)))
    {
    //
    //配置模块时钟源。
    //
    HibernateClockConfig (HIBERNATE_OSC_LOWDRIVE);
    
    //
    //存储这是一个系统重新启动,而不是从休眠中唤醒。
    //
    ui32Len = usnprintf (g_pcWakeBuf、sizeof (g_pcWakeBuf)、"%s"、
    G_ppcWakeSource[4]);
    
    //
    //设置标志以指示我们需要有效日期。 然后将设置日期
    //在 while (1)循环中。
    //
    G_bSetDate = true;
    //
    //将休眠计数消息存储到相应的 char 缓冲区中。
    //
    usnprintf (g_pcHibBuf、sizeof (g_pcHibBuf)、"Hibernate count =%u"、
    ui32休眠计数);
    
    //
    //启用 RTC 模式。
    //
    HibernateRTCEnable();
    
    //
    //将休眠模块计数器配置为24小时日历模式。
    //
    HibernateCounterMode (HIBERNATE_COUNTER_24HR);
    
    }
    
    }
    
    
    //
    //配置用作休眠唤醒源的 GPIO。 PK6配置为
    //唤醒源。 它在 EK-TM4C1294XL BoosterPack 2 (X7-17)上提供
    //和试验电路板分线连接器(X11-63)上。 接地短路至
    //生成唤醒请求。
    //
    GPIOPadConfigSet (GPIO_PORTK_base、GPIO_PIN_6、GPIO_Strength _2mA、
    (GPIO_PIN_TYPE_WAKE_LOW | GPIO_PIN_TYPE_STD_WPU);
    
    //
    //初始化按钮
    //
    ButtonInit();
    
    //
    //初始化 SysTick 中断以处理用户按钮。
    //
    SysTickPeriodSet (SysCtlClockGet ()/30);
    SysTickEnable();
    SysTickIntEnable();
    IntMasterEnable();
    
    //
    //启用处理器中断。
    //
    IntMasterEnable();
    
    //
    //如果休眠计数非常大,则可能已经存在
    //休眠存储器中的值,因此重置计数。
    //
    ui32休眠计数=(ui32休眠计数> 10000)? 0:ui32休眠计数;
    
    //
    //在进入无限循环之前初始化必要的标志。
    //
    G_bHibernate = false;
    
    //
    //清除终端并打印横幅。
    //
    UARTprintf ("\033[2J\033[H");
    UARTprintf ("%s\n"、g_pcWakeBuf);
    UARTprintf ("欢迎使用 Tiva C 系列 TM4C1294 LaunchPad!\n");
    UARTprintf ("休眠示例\n");
    UARTprintf ("键入'help'查看命令列表\n");
    UARTprintf (">");
    UARTFlushTx (false);
    
    //
    //设置下一次更新是第一次更新的标志。
    //这将触发下次更新时清除屏幕。
    //
    G_bFirstUpdate = true;
    G_ui8FirstLine = 5;
    
    //
    //永久循环。
    //
    while (1)
    {
    //
    //检查表示休眠时间无效的标志
    //模块。 如果设置、则强制设置为默认时间。
    //
    if (g_bSetDate)
    {
    //
    //清除标志。
    //
    G_bSetDate = false;
    
    //
    //将日期设置为默认值并将其提交到
    //休眠模块。
    //
    DateTimeDefaultSet();
    DateTimeSet();
    }
    
    //
    //更新在主程序上显示日期和时间的缓冲区
    //屏幕。
    //
    bUpdate = DateTimeDisplayGet (g_pcDateTimeBuf、
    sizeof (g_pcDateTimeBuf));
    
    //
    //是否可以显示新的日期和时间值?
    //
    if (bUpdate =true)
    {
    //
    //检查这是否是第一次更新。
    //
    if (g_BFirstUpdate = false)
    {
    //
    //保存当前光标位置。
    //
    UARTprintf ("\033[s");
    }
    
    //
    //重新发送当前状态和时间。
    //
    UARTprintf ("\033[%d;1H\033[K"、g_ui8FirstLine);
    UARTprintf ("当前日期和时间为:%s\n"、g_pcDateTimeBuf);
    UARTprintf ("\033[K");
    UARTprintf ("%s\n"、g_pcHibBuf);
    UARTprintf ("\033[K");
    UARTprintf ("要进入休眠模式、请键入'hib'并按 Enter 或按"
    "USR_SW1\n");
    
    //
    //检查这是否是第一次更新。
    //
    if (g_BFirstUpdate = false)
    {
    //
    //恢复光标位置。
    //
    UARTprintf ("\033[u");
    
    }
    其他
    {
    UARTprintf (">");
    }
    
    //
    //刷新 TX 缓冲区。
    //
    UARTFlushTx (false);
    
    //
    //清除第一个更新标志。
    //
    G_bFirstUpdate = false;
    
    }
    
    //
    //检查 UART 缓冲区中是否存在回车。
    //
    if (UARTPeek ('\r')!=-1)
    {
    //
    //检测到'\r',因此从用户处获取文本行。
    //
    UARTgets (g_pcInputBuf、sizeof (g_pcInputBuf));
    
    //
    //将线路从用户传递到命令处理器。
    //将对其进行解析并执行有效的命令。
    //
    i32CmdStatus = CmdLineProcess (g_pcInputBuf);
    
    //
    //处理命令错误的情况。
    //
    if (i32CmdStatus = CMDLINE_BAD_CMD)
    {
    UARTprintf ("无法识别命令!\n");
    }
    
    //
    //处理过多参数的情况。
    //
    否则、if (i32CmdStatus = CMDLINE_TOW_DONE_args)
    {
    UARTprintf ("命令处理器的参数太多!\n");
    }
    
    //
    //处理参数太少的情况。
    //
    否则、如果(i32CmdStatus = CMDLINE_TO_LING_args)
    {
    UARTprintf ("命令处理器的参数太少!\n");
    }
    
    UARTprintf (">");
    }
    
    //
    //检查用户是否要进入休眠状态。
    //
    if (g_bHibernate == true)
    {
    //
    //递增休眠计数并将其存储在中
    //电池供电内存。
    //
    ui32 HibernateCount++;
    HibernateDataSet (\ui32 HibernateCount、1);
    
    //
    //是-清除标志。
    //
    G_bHibernate = false;
    AppHibernateEnter();
    }
    }