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.

[参考译文] TDA4VE-Q1:时钟精度问题

Guru**** 2535150 points


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

https://e2e.ti.com/support/processors-group/processors/f/processors-forum/1559745/tda4ve-q1-clock-accuracy-issue

器件型号:TDA4VE-Q1


工具/软件:

尊敬的 TI 专家:

SDK:9.2

Linux:9.2

HW:我们自己的电路板

我们 现在使用 timer16 (0x2500000UL)、当前外部晶体振荡器为 19.2m、因此一次节拍时间的计算结果为 1/19200000。我们通过设置 TIMER_TMAR 寄存器的值来实现不同的计时器时钟精度、但实际结果不符合预期
1.软件的第一个版本将该计数值设置为 19200、* 1/19200000=1000US=1ms、而软件将 fsync 周期设置为 33 * 1ms。 在本例中、fsync 脉冲周期约为 33.1ms 或 33.2ms、精度为 1ms;
2.软件的第二个版本将该计数值设置为 1920、* 1/19200000=100us、软件将 fsync 周期设置为 333 * 100us。 在本例中、fsync 脉冲周期为 33.2ms-33.4ms、在 100us 时精度不准确;
3.第三个版本将此计数设置为 192、* 1/19200000=10us、软件将 fsync 周期设置为 3333 * 10us。 在这种情况下、fsync 脉冲周期为几毫秒、误差为毫秒、精度为 10us、该值不准确。
4、最终版本是服务器上当前的版本,不能向下调整精度。 我们改变了方法并向上调整了精确度。 根据原始 1ms 计数值、我们计算得出为 1.11、相当于 19200 * 1.11=21312。 软件已将脉冲周期设置为 30 * 1.11ms=33.3ms。 目前、精度已经过测试、符合其应用的要求;

当前问题是:
1.为什么将 TIMER_TMAR 值设置为 1920 和 21312 会在时钟精度调整为 33.3ms 时产生不同的结果?
2.计时器的最低时钟精度可以是 1ms 吗? 是否有办法提高时钟精度?
3、此外、我们发现、即使 TIMER_TMAR 寄存器值设置为 21312、也可以实现正常的 33.3ms 脉冲周期。 但是、在资源负载较高的某些情况下、这个 33.3ms 周期可能会波动、有时会达到 35ms。 是否有办法将脉冲周期稳定在 33.3ms?

BR。

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

    您好、

    由于美国假期、负责的工程师目前已离职。 感谢您发送编修。我们会重新检视您的建议。

    此致、

    Christina

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

    您好、

    我可以询问是否有新的更新吗?

    BR。

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

    您好:

    –0-

    您能描述一下如何测量周期吗?   测量是通过某种直接 PWM 输出信号进行的、还是通过某种正在计数并对中断做出响应的复杂 SW 进行的?

    扫描说明后、我解释您正在使用 TMAR 设置{1ms、100us、10us}的事件周期、然后在软件中使用某种计数软件以 33.XMS 周期为目标(通过计数 X33、x333、x3333)。   您报告的准确性似乎表明、在每种情况下、计数软件都关闭了 TMAR 设置的计数间隔的 1 个单位。  这意味着无论 SW 在做什么计数都可能关闭 1(可能是错误的启动或停止逻辑假设>Vs >=)。

    在您的解决方案中,您似乎已经调整间隔以考虑关一个错误,从而得到所需的目标速率。

    如果该软件由 TI 提供、那是哪一种?  可能它有一个错误(软件描述或内部逻辑)、或者可能没有正确使用 API。

    –1-

    如果我对基计数器进行一些简单的测试、我会看到一个在输入时钟速率下干净递增的基址。  直接从专用裸机调试任务进行采样和绘图时、我看不到任何不连续性。

    您能提供所有 TIMER16 寄存器的转储并更好地描述测量方式吗?  Perhpas 添加该代码将允许重新生成或查找“Off by 1“问题。  

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

    尊敬的 Richard W:

    您能描述如何衡量时间段吗?   测量是来自某种直接 PWM 输出信号还是某种正在计数并对中断做出响应的复杂 SW?

    使用计时器的目的是在记录每个脉冲的启动时间的同时实现 PWM 功能。 我们使用两种方法来测量脉冲周期:μ s

    计时器 16 的中断函数中记录的时间将定期打印在应用上、以确定脉冲周期是否准确。

    2.使用示波器进行测量。

    如果该软件由 TI 提供、那么这是哪一个?  可能它有一个错误(软件描述或内部逻辑)、或者可能 API 未正确使用。

    软件实现方法不来自 TI。 我在以下代码中提供了中断函数的实现。

    您能否提供所有 TIMER16 寄存器的转储并更好地描述测量方式。  [/报价]

    软件实现方法不来自 TI。 我在下面的文本中提供了中断函数的实现。

    static void OsSysTimer_ISR(uintptr_t arg)
    {
        uint32_t tempTCRR, reloadValue;
        //static uint32_t cnt = 5;
    
        /* Disable the Timer interrupts */
        OS_WR_REG32(OS_SYS_TIMER_BASE + OS_TIMER_IRQENABLE_CLR, OS_TIMER_IRQENABLE_SET_MAT_EN_FLAG_MASK); 
    	
        //tempTMAR = OS_RD_REG32(OS_SYS_TIMER_BASE + OS_TIMER_TMAR); 
        tempTCRR = OS_RD_REG32(OS_SYS_TIMER_BASE + OS_TIMER_TCRR); 
        reloadValue = tempTCRR + OS_PL_SYSTIMER_RELOAD_VAL;
    
        /* acknowledge the interrupt */
        OS_WR_REG32(OS_SYS_TIMER_BASE + OS_TIMER_IRQSTATUS, OS_TIMER_IRQSTATUS_MAT_IT_FLAG_MASK);
    
        /* Load the register with the match value */
        OS_WR_REG32(OS_SYS_TIMER_BASE + OS_TIMER_TMAR, reloadValue);
    
        //OsCnt_InternalIncreaseCounter(CoreID, Os_CoreCfg[CoreID].startCntId);
        /* Enable the Timer interrupts */
        OS_WR_REG32(OS_SYS_TIMER_BASE + OS_TIMER_IRQENABLE_SET, OS_TIMER_IRQENABLE_SET_MAT_EN_FLAG_MASK); 
        /* Operation on the system clock interrupt register. */
    
        isr_cnt = isr_cnt + 1;
        if(isr_cnt == 1)
        {
            // how to calculate timeStamp ? you can refer to appLogGetGlobalTimeInUsec function
            if (runFreq != 0) {
                timeStamp = (*(volatile uint64_t *)(GTC_TIMER_MAPPED_BASE + 0x8)) / runFreq;
            } else {
                timeStamp = (*(volatile uint64_t *)(GTC_TIMER_MAPPED_BASE + 0x8)) / 200;
       }
    
            (*(volatile unsigned int *) (0x42110000U + 0x18U))  = 0x00008000; /* Set HIGH */
            
        }else if(isr_cnt == 8)
        {
            (*(volatile unsigned int *) (0x42110000U + 0x1CU))  = 0x00008000; /* Set LOW */
        }else if(isr_cnt == 30)
        {
            isr_cnt = 0;
        }
    
    }
    

    BR。

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

    您好:

    请提供所有寄存器的 JTAG 转储。  如果设置了已发布功能、则存在访问规则、如果不遵循、可能会导致意外结果。  其他寄存器也可能有副作用。  直接检查 JTAG 寄存器就像是使用 示波器 和软件打印进行检查一样、因为它可以从不同的角度和偏置较小的角度展示效果。

    此致、
    理查德·W·