您好,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。只有下一次才会清除。正因为如此,我的闹钟中断服务完全失灵了。
是否在实施过程中出了什么问题?
谢谢!
你好@AmanKumbhani,
,我复制了你的问题。我将在内部进行检查,以确认这是否是一个错误,或者这两个功能是否相互排斥。这可能需要一些时间。
不过,就您的应用而言,我认为以下 if 条件可以起到警报中断的作用:
if (rtcDate.second == 30U)
{
__asm(" NOP");
__ asm(" NOP");
__asm(" NOP");
}
BR
Habib
嗨,哈比卜
感谢您的回复。老实说,我没有固定的用途。我正在对此进行测试,以便通过包装器为应用程序层提供功能,因此遇到了这个问题。
您能在自己的电脑上重现这个问题吗?
谢谢您!
你好,@阿曼-库姆巴尼、
对延迟回复表示歉意。为了更好地为您提供支持,能否请您说明申请的目的?
在我看来,您似乎可以完全依赖于周期性中断,因为您已经在每秒钟输入一次中断。你可以像在以下几行代码中一样简单地轮询秒值:i
f (rtcDate.Second == 30U)
{
__asm(" NOP");
__ asm (" NOP ");
__asm (" NOP ");
}
最终,两种方法都会触发信号相同的中断,因此仅使用定期中断可能会简化您的实现。
BR
Habib.
您好@AmanKumbhani,
,我将运行测试来复制这一问题,并详细查看这一行为。感谢您的耐心等待。
BR
Habib.
嘿、
谢谢你的澄清!我会研究一下,并按照您的建议进行一次测试。
最好的
安缦
你好,@阿曼-库姆巴尼、
造成这一问题的根本原因有两个。第一个问题与您配置 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.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