2173508_zh-CN

キャンセル
次の結果を表示 
表示  限定  | 次の代わりに検索 
もしかして: 

2173508_zh-CN

2173508_zh-CN

在 SNVS 内的 HPRTC 上定期& 警报中断

您好,NXP团队:

我正试图配置每 1 秒一次的周期性中断和 30 秒后的警报中断。我的 ISR 看起来是这样的

void SNVS_HP_NON_TZ_IRQHandler(void)
{
    volatile uint32_t flagStatus = SNVS_HP_RTC_GetStatusFlags(SNVS);
    volatile uint32_t result = flagStatus & kSNVS_RTC_PeriodicInterruptFlag;
    snvs_hp_rtc_datetime_t rtcDate;

    if (result)
    {
        __asm(" NOP");
        SNVS_HP_RTC_GetDatetime(SNVS, &rtcDate);
        dbg_info("Periodic Interrupt @ %04hd-%02hd-%02hd %02hd:%02hd:%02hd\r\n", rtcDate.year, rtcDate.month, rtcDate.day,
            rtcDate.hour, rtcDate.minute, rtcDate.second);
        
        if (rtcDate.second == 30U)
        {
            __asm(" NOP");
            __asm(" NOP");
            __asm(" NOP");
        }
        SNVS_HP_RTC_ClearStatusFlags(SNVS, kSNVS_RTC_PeriodicInterruptFlag);
    }
    if (SNVS_HP_RTC_GetStatusFlags(SNVS) & kSNVS_RTC_AlarmInterruptFlag)
    {
        __asm(" NOP");
        dbg_info("Alarm:\r\n");
        /* Clear alarm flag */
        SNVS_HP_RTC_ClearStatusFlags(SNVS, kSNVS_RTC_AlarmInterruptFlag);
    }
    SDK_ISR_EXIT_BARRIER;
}

我的初始化过程是这样的

 SNVS_HP_RTC_GetDefaultConfig(&snvsRtcConfig);
    snvsRtcConfig.periodicInterruptFreq = 15;
    SNVS_HP_RTC_Init(SNVS, &snvsRtcConfig);

    dbg_info("SNVS HP example:\r\n");

    /* Set a start date time and start RT */
    rtcDate.year   = 2014U;
    rtcDate.month  = 12U;
    rtcDate.day    = 25U;
    rtcDate.hour   = 19U;
    rtcDate.minute = 0;
    rtcDate.second = 0;

    /* Set RTC time to default time and date and start the RTC */
    SNVS_HP_RTC_SetDatetime(SNVS, &rtcDate);
    SNVS_HP_RTC_StartTimer(SNVS);

    

    dbg_info("\r\n");

    SNVS_HP_RTC_GetDatetime(SNVS, &rtcDate);
    rtcDate.second = 30u;

    SNVS_HP_RTC_SetAlarm(SNVS, &rtcDate);

    /* Get alarm time */
    SNVS_HP_RTC_GetAlarm(SNVS, &rtcDate);
    /* Print alarm time */
    dbg_info("Alarm will occur at: %04hd-%02hd-%02hd %02hd:%02hd:%02hd\r\n", rtcDate.year, rtcDate.month, rtcDate.day,
            rtcDate.hour, rtcDate.minute, rtcDate.second);

/* Enable SNVS alarm interrupt */
    SNVS_HP_RTC_EnableInterrupts(SNVS, kSNVS_RTC_AlarmInterrupt);
    SNVS_HP_RTC_EnableInterrupts(SNVS, kSNVS_RTC_PeriodicInterrupt);

    NVIC_EnableIRQ(SNVS_HP_NON_TZ_IRQn);

在我的 ISR 中,我观察到当警报中断和定期中断同时发生时(HPSR 中的两个位都被设置),定期定时器标志将在 ISR 中首先被清除,因为它具有隐含优先级(如果检查定期 ISR,则优先)。在 if 块中,当定期计时器状态标志被清除时,由于某种原因,我看到我的警报状态标志也被清除,而定期计时器的定时器标志将再次转换为 1。只有下一次才会清除。正因为如此,我的闹钟中断服务完全失灵了。


是否在实施过程中出了什么问题?


谢谢!

Re: Periodic & alarm interrupts on HPRTC within SNVS您好!

了解。目前,我将只使用周期定时器来充当警报中断的角色。

感谢您的及时支持!
Re: Periodic & alarm interrupts on HPRTC within SNVS

你好@AmanKumbhani

,我复制了你的问题。我将在内部进行检查,以确认这是否是一个错误,或者这两个功能是否相互排斥。这可能需要一些时间。
不过,就您的应用而言,我认为以下 if 条件可以起到警报中断的作用:
if (rtcDate.second == 30U)
{
__asm(" NOP");
__ asm(" NOP");
__asm(" NOP");
}
BR
Habib

Re: Periodic & alarm interrupts on HPRTC within SNVS

嗨,哈比卜

感谢您的回复。老实说,我没有固定的用途。我正在对此进行测试,以便通过包装器为应用程序层提供功能,因此遇到了这个问题。

您能在自己的电脑上重现这个问题吗?

谢谢您!

Re: Periodic & alarm interrupts on HPRTC within SNVS

你好,@阿曼-库姆巴尼

对延迟回复表示歉意。为了更好地为您提供支持,能否请您说明申请的目的?
在我看来,您似乎可以完全依赖于周期性中断,因为您已经在每秒钟输入一次中断。你可以像在以下几行代码中一样简单地轮询秒值:i
f (rtcDate.Second == 30U)
{
__asm(" NOP");
__ asm (" NOP ");
__asm (" NOP ");
}
最终,两种方法都会触发信号相同的中断,因此仅使用定期中断可能会简化您的实现。

BR
Habib.

Re: Periodic & alarm interrupts on HPRTC within SNVS

您好@AmanKumbhani

,我将运行测试来复制这一问题,并详细查看这一行为。感谢您的耐心等待。
BR
Habib.

Re: Periodic & alarm interrupts on HPRTC within SNVS

嘿、


谢谢你的澄清!我会研究一下,并按照您的建议进行一次测试。


最好的

安缦

Re: Periodic & alarm interrupts on HPRTC within SNVS

你好,@阿曼-库姆巴尼

造成这一问题的根本原因有两个。第一个问题与您配置 RTC 警报的方式有关:

    SNVS_HP_RTC_EnableInterrupts(SNVS, kSNVS_RTC_AlarmInterrupt);
    SNVS_HP_RTC_EnableInterrupts(SNVS, kSNVS_RTC_PeriodicInterrupt);

如第 24.6.1.3 章所述在 RM 中的 "SNVS_HP 控制寄存器(HPCR)"中,使能警报 "HPTA_EN "的位与 32 kHz 时钟同步。这意味着,当您设置其值时,需要等待它的更新,因为内核的运行速度通常比 32 kHz 快得多。这种等待机制的一个示例可以在启用 "RTC_EN "位的函数"SNVS_HP_RTC_StartTimer" 中看到,如下图所示:

Habib_MS_0-1764718923411.pngHabib_MS_0-1764718923411.png

另一方面,第二个问题与函数 "SNVS_HP_RTC_ClearStatusFlags "的工作方式有关。该函数对寄存器执行 OR 运算。下面就是一个例子:

寄存器:11 (两个标志都已设置。)
屏蔽:10(kSNVS_RTC_PeriodicInterruptFlag)
OR:11

因此,当调用 "SNVS_HP_RTC_ClearStatusFlags "时,它将向 HPSR 寄存器写入 "0b11",从而清除周期和警报标志,因为这些位通过写入 1 来清除。因此,在清除状态标志之前,必须先读取这两个状态标志。因此,以下代码将导致错误:

    if (SNVS_HP_RTC_GetStatusFlags(SNVS) & kSNVS_RTC_AlarmInterruptFlag)
    {
        __asm(" NOP");
        dbg_info("Alarm:\r\n");
        /* Clear alarm flag */
        SNVS_HP_RTC_ClearStatusFlags(SNVS, kSNVS_RTC_AlarmInterruptFlag);
    }

希望对您有所帮助。
BR
Habib

タグ(1)
評価なし
バージョン履歴
最終更新日:
‎12-03-2025 03:30 AM
更新者: