如何解决使用 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 举报,一经查实,本站将立刻删除。