微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

使用 RTC 时钟编程 1ms 延迟

如何解决使用 RTC 时钟编程 1ms 延迟

我目前正在使用 S32k142 微控制器。 我想使用 RTC 时钟配置 1ms 延迟。我有一个外部 RTC 时钟(32.768KHz),它已配置为驱动微控制器的 RTC 模块。 我已经编写了以下程序:

 void wait_1ms_RTC(void)
{
    
    UINT32 tpr = (UINT32)RTC->TPR; // RTC Time Prescaler Register: increments at a freq of 32.768KHz
    UINT32 tsr = (UINT32)RTC->TSR; // RTC Time Seconds Register: increments every second

    tpr = tpr + (UINT32)32; // 32->1ms(32*30.51us=976.32us)
    if (tpr <= 32767)
    {
        while (((UINT32)RTC->TPR <= tpr)&& ((UINT32)RTC->TSR <= tsr));
    }
    else
    {
        while (((UINT32)RTC->TPR <= (tpr - 32768))&& ((UINT32)RTC->TSR <= tsr+1));
    }
}

这段代码只是简单地读取 TPR 和 TSR 寄存器,并等待 TPR 寄存器和 TSR 寄存器达到与 1ms 对应的某个值。 这在大多数情况下都有效,除非在少数情况下它不会产生 1 毫秒的延迟,我假设它是在翻转期间发生的,但仍然无法弄清楚代码中的问题究竟出在哪里。

关于如何解决这个问题的任何想法?

解决方法

你把它复杂化了;你只需要TPR。通过将 TPR 值左移 1 位,并将其分配给 uint16_t,自然模 216 算法会为您处理翻转:

#define RTC_TPR_MILLISEC ((32768<<1)/1000)
void wait_1ms_RTC(void)
{
    // RTC Time Prescaler Register: 0 to 2^15,// shift-left 1 but to make it 2^16 so uint16_t modulo arithmetic works
    uint16_t start = RTC->TPR << 1 ; 

    while( (RTC->TPR << 1) - start < RTC_TPR_MILLISEC )
    {
        // spin 
    }
}

事实上它可能比这更简单。 user manual 表明 TPR 是一个 16 位寄存器,并且当 TPR:14 从 1 转换为 0 时,TSR 会递增。这并不意味着 TPR 是 15 位值,并且计数器在 32767 之后重置为零. 我不熟悉这部分,但如果实际上它是一个完整的 16 位计数器,如文档所建议的那样,则不需要移位:

#define RTC_TPR_MILLISEC (32768/1000)
void wait_1ms_RTC(void)
{
    // RTC Time Prescaler Register: 0 to 2^16
    uint16_t start = RTC->TPR ; 

    while( RTC->TPR - start < RTC_TPR_MILLISEC )
    {
        // spin 
    }
}

如果您不确定为什么会这样,请参阅 How to deal with a wrapping counter in embedded C(示例中有一个 32 位计数器,但同样适用于 16 位)。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。