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.

[参考译文] LAUNCHXL-F2800137:内部和外部时钟之间的 TMS320F2800137 eCAP 捕捉计数不匹配

Guru**** 2911190 points

Other Parts Discussed in Thread: LAUNCHXL-F2800137

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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1645924/launchxl-f2800137-tms320f2800137-ecap-capture-count-mismatch-between-internal-and-external-clock

器件型号: LAUNCHXL-F2800137

我的设置:

  • SYSCLK = 120MHz
  • 1 个 eCAP 计数= 8.33ns
  • 输入 PWM 导通时间= 1200µs

观察到的行为:

  • 使用 外部时钟时、捕获的计数会正确转换为 1200µs
  • 使用 内部时钟时、捕获的计数转换为 1210µs

计算方法:

预期计数:

1200 us / 8.33 ns = 144000 counts

但内部时钟测量显示:

145200 counts

这给出了关于 10µs 误差的信息。

我的问题:

有人能解释为什么会发生这种情况吗?

是否有任何人有利用 内部 eCAP 时钟测量精确 PWM 导通时间的解决方案



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

    您好、

    很抱歉、延迟的回复。 您能给代码片段一段吗?  

    谢谢、

    Divesh

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

    尊敬的 Divesh:

    感谢您的回答。

    我正在使用 LAUNCHXL-F2800137 上的 eCAP 来进行 PWM 脉宽测量。

    我的设置:

    • GPIO16 上的 eCAP 输入

    • SYSCLK = 120MHz

    • eCAP 在单次触发模式下使用

    • 在每个捕获事件时启用计数器复位

    我的目标是仅以微秒为单位准确测量 PWM 导通时间。

    我观察到了一些与 PLL 时钟源选择相关的有趣内容。

    当我使用:

    #define USE_PLL_SRC_XTAL
    

    测得的导通时间准确且稳定。

    但当我使用:

    #define USE_PLL_SRC_INTOSC
    

    导通时测得的时间会发生变化并变得不准确。

    例如:

      • PWM 预期导通时间≈1500us

      • 使用 XTAL 源→正确测量到接近 1500us

      • 使用 INTOSC 源时→测量值会显著变化 (~1510)  

        例如:

        • PWM 预期导通时间≈1500us

        • 使用 XTAL 源→正确测量到接近 1500us

        • INTOSC 源→μ V 测量值始终变化(约为 1510us)

        我还观察到、对于不同的 PWM 导通时间、该失调电压是恒定的。
        对于任何导通时间值、测量结果都会移动大约+10us。

        由于该偏移是恒定的且稳定的、因此 eCAP 捕捉本身似乎正常工作、但从 INTOSC 得出的有效 SYSCLK 频率可能与 DEVICE_SYSCLK_FREQ 时间转换计算中使用的预期略有不同。

    因此、我怀疑内部振荡器精度可能会影响:

    • SYSCLK 频率

    • eCAP 计数器时序

    • 时间转换计算

    以下是我的 eCAP 配置。

    我配置了:

    • 单次捕获模式

    • 捕获到 Event4

    • 每次发生事件时计数器复位

    • 没有预分频器

    事件序列:

    • EVENT1 =下降沿

    • Event2 =上升沿

    • Event3 =下降沿

    • Event4 =上升沿

    因此:

    • CAP2 =低电平/关断时间

    • CAP3 =高电平/导通时间

    • CAP4 =低电平/关断时间

    eCAP 配置:

    ECAP_setCaptureMode(myECAP0_BASE,
                        ECAP_ONE_SHOT_CAPTURE_MODE,
                        ECAP_EVENT_4);
    
    ECAP_setEventPrescaler(myECAP0_BASE, 0U);
    
    ECAP_setEventPolarity(myECAP0_BASE,
                          ECAP_EVENT_1,
                          ECAP_EVNT_FALLING_EDGE);
    
    ECAP_setEventPolarity(myECAP0_BASE,
                          ECAP_EVENT_2,
                          ECAP_EVNT_RISING_EDGE);
    
    ECAP_setEventPolarity(myECAP0_BASE,
                          ECAP_EVENT_3,
                          ECAP_EVNT_FALLING_EDGE);
    
    ECAP_setEventPolarity(myECAP0_BASE,
                          ECAP_EVENT_4,
                          ECAP_EVNT_RISING_EDGE);
    
    ECAP_enableCounterResetOnEvent(myECAP0_BASE,
                                   ECAP_EVENT_1);
    
    ECAP_enableCounterResetOnEvent(myECAP0_BASE,
                                   ECAP_EVENT_2);
    
    ECAP_enableCounterResetOnEvent(myECAP0_BASE,
                                   ECAP_EVENT_3);
    
    ECAP_enableCounterResetOnEvent(myECAP0_BASE,
                                   ECAP_EVENT_4);
    
    ECAP_startCounter(myECAP0_BASE);
    
    ECAP_enableTimeStampCapture(myECAP0_BASE);
    
    ECAP_reArm(myECAP0_BASE);
    
    ECAP_enableInterrupt(myECAP0_BASE,
                         ECAP_ISR_SOURCE_CAPTURE_EVENT_4);
    

    ISR:

    __interrupt void INT_myECAP0_ISR(void)
    {
        cap2Count =
            ECAP_getEventTimeStamp(myECAP0_BASE,
                                   ECAP_EVENT_2);
    
        cap3Count =
            ECAP_getEventTimeStamp(myECAP0_BASE,
                                   ECAP_EVENT_3);
    
        cap4Count =
            ECAP_getEventTimeStamp(myECAP0_BASE,
                                   ECAP_EVENT_4);
    
        // CAP3 used as PWM ON time
        f32gtimefromcap3Count_us =
            ((float32_t)cap3Count * 1000000.0f) /
            DEVICE_SYSCLK_FREQ;
    
        ECAP_clearInterrupt(myECAP0_BASE,
                            ECAP_ISR_SOURCE_CAPTURE_EVENT_4);
    
        ECAP_clearGlobalInterrupt(myECAP0_BASE);
    
        ECAP_reArm(myECAP0_BASE);
    
        Interrupt_clearACKGroup(
            INT_myECAP0_INTERRUPT_ACK_GROUP);
    }
    

    请确认:

    1. 使用 INTOSC 而不是 XTAL 时、预期的时序差异是什么?

    2. eCAP 是否直接依赖于 SYSCLK 精度来进行时间戳测量?

    3. 使用 INTOSC 时、是否有任何推荐的方法来提高捕获时序精度?

    谢谢。

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

    您好、

    1.你注意到的观察是正确的。  在 10MHz 时、内部振荡器的输出频率的精度范围为–1.8%至 1%(根据数据表)。如果同样用作 SYSCLK 源、则它在 120MHz 上可能会产生大约 8.33 微秒的误差。 此外、温度变化会影响内部振荡器输出频率的精度。

    2.可以、eCAP 时间戳测量取决于 SYSCLK。 因此、建议在时序要求严格(意味着精度很重要)的应用中使用 XTAL。

     根据  TRM 的第 3.7.1 节“时钟源“(技术参考手册) 、为了提高 INTOSC2 的精度、可以使用外部电阻器 (ExtR) 模式。 该模式允许将高精度外部电阻器添加到电路板并连接到支持 ExtR 的引脚。 请参阅 TMS320F280013x 实时微控制器数据表、了解每个封装上支持 ExtR 的引脚。

    更多详细信息、请参阅 TRM 中的时钟章节。

    谢谢、

    Divesh