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.

[参考译文] TMS320F2810:错误的硬件定时器计数器值

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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/968458/tms320f2810-incorrect-hardware-timer-counter-value

器件型号:TMS320F2810
Thread 中讨论的其他器件:CC3200

大家好、

         我们使用硬件计时器进行 UNIX 时间戳增量、以秒为单位。 但硬件计时器始终以毫秒为单位中断。 下面是我们使用的代码。 我们发现的问题是、在从服务器获取到 MCU 的实际时间戳后、我们每4小时更新一次时间戳、MCU 时间戳比实际更新服务器时间戳快2秒。 如果我们不更新时间戳、时间可能为4或5天、时间戳将比实际当前时间戳快大约15秒。

静态中断 void SysTick InterruptHandler()
{
ui64SysTickCounter++;

/*需要调用 extern 变量以增加 UNIX 时间戳*/
if (g_UnixTimestamp!= 0)
{
if ((ui64SysTickCounter % 1000)=0)
{
G_UnixTimestamp++;
}
}

PieCtrlRegs.PIEACX.ALL = PIEACK_Group1;
}

静态空 Timer0Initialize (浮点频率、浮点周期)
{
uint32_t tick;
tick =(uint32_t)(freq * period);
CpuTimer0Regs.PRD.All =节拍;
CpuTimer0Regs.TPR.ALL = 0;
CpuTimer0Regs.TPRH 全部= 0;

CpuTimer0Regs.TCR.bit.TSS = 1; // 1 =停止计时器,0 =启动/重新启动计时器
CpuTimer0Regs.TCR.bit.TRB = 1; // 1 =重新加载计时器
CpuTimer0Regs.tcr.bit.soft = 1;
CpuTimer0Regs.TCR.bit.FREE = 1; //定时器自由运行
CpuTimer0Regs.tcr.bit.tie = 1; // 0 =禁用/ 1 =启用计时器中断

ui64SysTickCounter = 0;

EALLOW;
PieVectTable.TINT0 =&SystickInterruptHandler;
EDIS;

CpuTimer0Regs.TCR.bit.TSS = 0;

IER |= 0x0001;

PieCtrlRegs.PIEIER1.bit.INTx7=1;
}

void Hwtimer_Initialize (void)
{
Timer0Initialize (150000000、0.001);// 150kHz 和1ms 计时器
。} 

那么、代码中可能会出现什么问题、以及我们需要在代码中实现哪些其他功能。

G_UnixTimestamp 是时间戳、显示速度始终比实际电流时间快2秒。

谢谢

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

    您好、Ganesh、

    您是否参考 了此下载中的 example_281xCpuTimer.c 文件 ?

    C:\tidcs\c28\DSP281x\V120\DSP281x_examples\cpu_timer。

    定时器初始化和配置的相应函数可在以下文件中找到:

    C:\tidcs\c28\DSP281x\V120\DSP281x_common\source\DSP281x_CpuTimers.c

    C:\tidcs\c28\DSP281x\V120\DSP281x_headers\include\DSP281x_CpuTimers.h

     [引用 USER="Ganesh Gurung58"]我们发现的问题是,在从服务器获取到 MCU 的实际时间戳之后,每4小时更新一次时间戳,MCU 时间戳比实际更新服务器时间戳快2秒。

    服务器时间戳从哪个点开始?

    此致、

    Marlyn

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

    您好、Marlyn、

             谢谢、我将深入探讨。 我们在器件上电时会获得时间戳、CC3200连接到 WiFi 后、就会获得时间戳。 我会说、在 WiFi 连接1分钟后。

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

    你(们)好。

           我读取了示例代码。 Hmm 看起来与我们所做的不同。 不过我有疑问。

    在您的示例中、您按如下方式设置1秒计时器中断

    ConfigCpuTimer (&CpuTimer0、100、1000000);


    如果我需要执行1ms 计时器中断、我应该执行什么设置。

    它是  ConfigCpuTimer(&CpuTimer0,100,1000000000)吗?

    或  

    它是  ConfigCpuTimer(&CpuTimer0,100,1000); ?

    顺便说一下、我们如何知道芯片中的 CPU 频率?

    谢谢

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

    你(们)好。

    我想我了解 CPU 时钟是如何设置的。 外部时钟为30MHz,  SysCtrlRegs.PLLCR.bit.DIV = 0xA;//设置为150MHz。 PLL 为(30*10)/2)。 因此 CPU 时钟应为150 MHz

    从上面提到的代码开始、 Timer0Initialize (150000000、0.001);它基本上执行1ms 计时器中断。 我们的代码似乎是正确的。

    那么、还有什么问题呢?

    谢谢

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

    您好、Ganesh、

    对于第一个问题、如果您要使用示例函数、那么1ms 计时器将是  :ConfigCpuTimer (&CpuTimer0、100、 1000);  

    [引用 USER="Ganesh Gurung58"]这样 CPU 时钟应该是150 MHz。  

    是的、这应该是正确的。 您拥有的代码应生成1ms 计时器中断。 另一种编写方法是  Timer0Initialize (150、1000);

    写入 PLLCR 寄存器 DIV 字段后、您是否等待 131072个 OSCCLK 周期、以使 PLL 变得稳定?

    以下是 《TMS320x281x DSP 系统控制和中断参考指南》第51页的摘录

    PLLCR 寄存器的 DIV 域(位3−0)用于更改器件的 PLL 乘法器。 当 CPU 写入 DIV 位时、PLL 逻辑将 CPU 时钟(CLKIN)切换到 OSCCLK/2。 一旦 PLL 稳定并锁定在新的指定频率、PLL 就会将 CLKIN 切换到新频率、如图3−6所示。 PLL 从 OSCCLK/2切换到新频率所需的时间为131072个 OSCCLK 周期。 对于时间关键型软件、您应该在写入 PLLCR 寄存器后插入所需锁定周期的软件延迟、以便 PLL 完成锁定序列

    C:\tidcs\c28\DSP281x\V120\DSP281x_common\source\DSP281x_sysctrl.c 内的 InitPll 函数中显示了这方面的一个示例

    此致、

    Marlyn

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

    您好、Marlyn、

    是的、我们等待131072 OSCCLK。

    空 InitSysCtrl()
    {
    volatile uint32_t ui32LockCounter;
    EALLOW;
    SysCtrlRegs.WDCR = 0x0068;
    SysCtrlRegs.PLLCR.bit.DIV = 0xA;//设置为150MHz。 PLL 处于(30*10)/2
    //等待 PLL 锁定
    对于(ui32LockCounter = 0;ui32LockCounter <((131072u / 2U)/ 12U);ui32LockCounter++)
    {
    //仅循环
    }
    //设置外设时钟
    SysCtrlRegs.HISPCP 位.HSPCLK = 3;//时钟设置为25MHz
    SysCtrlRegs.LOSPP.bit.LSPCLK = 2;//时钟设置为37.5MHz
    } 

    在此 MCU 中、150MHz 是否非常稳定?

    谢谢

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

    您好、Ganesh、

    有趣的实验。

    30MHz 时钟输入的精确度如何?

    振荡器输出可能会漂移、也可能与中心频率有很小的偏差。  假设容差规格为50 PPM、它将在几个小时内累加。  

    50 (PPM)* 30 (MHz)* 5 (xPLL)* 3600 (秒)* 4小时= 0.7秒的额外脉冲值;您的振荡器可能会稍微关闭一点。  

    时钟漂移、就像您一样、它们需要定期同步以同时参考。 将毫秒计时器周期增加20个计数、达到150020、以减少时间漂移。 此外、您如何同步时间? 您是否还清除毫秒计数器? 为什么是64位?

    谢谢、

    Joe

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

    Joe、您好!

          振荡器输出可能会漂移、小偏差可能会改变频率变化、正如您在前面的消息中提到的那样。

    好的问题是、我们在更新时间戳时没有清除毫秒计数器值、但这将仅提供1秒的差异。  我们在从服务器收到时间戳时更新 g_UnixTimestamp。  

    另一个很好的问题是、为什么我们使用64位的毫秒。 嗯、实际上32位应该足够了。 如果我们使用64位作为毫秒计数器、它会产生什么影响吗?

    我们将在将毫秒计时器周期增加20后通知您。 让我们来看看它是怎么发生的。

    谢谢