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.

[参考译文] TMS320F280025C:Timer1测量时间不准确

Guru**** 2460850 points
Other Parts Discussed in Thread: C2000WARE

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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1061224/tms320f280025c-timer1-measures-time-inaccurately

器件型号:TMS320F280025C
主题中讨论的其他器件:C2000WARE

你好。

我编写了一个基于 Timer1的自定义延迟函数、并尝试每20us 切换一次 GPIO 引脚。

如下图所示、切换每22-24us 进行一次。

void initTimer1(void)
{
    EALLOW;
    CpuSysRegs.PCLKCR0.bit.CPUTIMER1=1;
    EDIS;
    CpuTimer1Regs.TCR.bit.TSS=1;
    CpuTimer1Regs.PRD.all=0xFFFFFFFF;
    CpuTimer1Regs.TPR.bit.TDDR=9;
    CpuTimer1Regs.TPRH.bit.TDDRH=0;
    CpuTimer1Regs.TCR.bit.TRB=1;
    CpuTimer1Regs.TCR.bit.TSS=0;
}

uint64_t micros(void)
{
    uint64_t time1;
    time1 = time0 + (0xFFFFFFFF-CpuTimer1Regs.TIM.all);
    return time1/10;
}

void delay_us(uint64_t delay)
{
    uint64_t time1=micros();
    while((micros()-time1)<delay);
    return;
}

__interrupt void timer1ISR(void)
{
    time0 += (429.5*1000000);
}

void main(void){
    Device_init();
    initTimer1(0xFFFFFFFF);

    EALLOW;
    GpioCtrlRegs.GPAGMUX1.bit.GPIO0 = 0x00;
    GpioCtrlRegs.GPAMUX1.bit.GPIO0 = 0x00;
    GpioCtrlRegs.GPADIR.bit.GPIO0=1;
    EDIS;
    GpioDataRegs.GPACLEAR.bit.GPIO0=1;
    _disable_interrupts();

    while(1)
    {
        delay_us(20);
        GpioDataRegs.GPATOGGLE.bit.GPIO0=1;
    }
}

我的代码中没有太多内容、2-4美元的开销是合理的还是其他的? 是否有任何方法可以使延迟更精确? 我之所以这样写、是因为我注意到、即使 C2000Ware 延迟函数也有类似这样的小漂移、尽管漂移不大。

如果能提供任何援助,将不胜感激。

此致、

Vishnu

详细信息:

我将 Timer1设置为以0.1us 的分辨率进行计数、并编写了自定义函数来测量代码中经过的时间(micros())、还使用 micros()函数编写了延迟函数(代码中的 delay_us())。

micros()函数只读取 TIMH:TIM 计数器、并从0xFFFFFFFF (给定周期)中减去它、因为它是递减计数器。 这将为我提供自计时器初始化以来的当前经过时间、以微秒为单位。 在计时器 ISR 中、我将维护一个变量、该变量在计时器计数器每次到达0时递增、这是已知的持续时间。 在 delay 函数中,我只是读取输入函数的时间,然后不断调用 micros()函数,直到所需的时间经过(从当前时间减去进入时间并等待它超过阈值)。

然后在 main()中,我在调用 delay_us()后切换 GPIO。

微控制器以默认的100MHz 运行。 在整个循环中、唯一定期重复的操作是寄存器读取(TIM)、两个算术运算和一个 GPIO 切换- 2-4美元的开销似乎有点过大。

此外、由于我还不关心计时器 ISR、我在禁用中断后尝试运行它、但仍然存在此问题-这排除了中间触发其他一些 ISR 的可能性。

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

    您好!

    由于您要分频 time/10、因此您要截断小数点、因为您要返回 uint64_t 我认为这可能会导致计算错误。

    您能否使用计时器中断并在 ISR 中切换 GPIO? 我们在 C2000Ware 中提供了一个示例、您可以参考该示例。

    如果要这样做,则可能需要从 micros()返回浮点值。

    此致、

    Nirav

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

    Nirav、您好!

    感谢您的回复。 我按照您的建议将 uint64_t 替换为 float、但仍然发现相同的错误。 我知道由于截断可能会出现一些错误、但2-4us 的错误是否太大? 尤其是由于微控制器以100MHz 的频率运行。 无论采用哪种方法,将 micros()的返回值和 main()中的相应变量更改为 float 似乎都没有效果。 我在 ISR 内部切换 GPIO、将 PRD 设置为10 (这意味着我希望 GPIO 每1us 切换一次、因为 TIMH:TIM 应每0.1us 递减一次。 顺便说一下、TPR[TDDRH:TDDR]= 9)但我仍然发现一些错误、如下图所示。

    我看了 C2000Ware 示例、它似乎只是在 CPUTIME_VARS 结构内递增 uint32_t 变量。 示例项目中的周期大得多-中断每秒触发一次。 老实说、即使在20us 的时间段、这个问题也会消失(例如、每10us 切换一次)。 但是、对于我的应用、如果分辨率为0.1us 将会很好。

    即使我将 TPR[TDDRH:TDDR]设置为99 (以便 每1us 而不是0.1us 递减一次 TIMH:TIM 并将 PRD 设置为1、我仍然发现 ISR 内部的 GPIO 切换是每2us 而不是1us 发生一次。

    请告诉我、您是否能想到这可能是什么原因。 或者我是否可以提供任何其他详细信息。

    谢谢、此致、

    Vishnu

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

    您好,Vishnu,

    您正在使用什么 PLL 配置? 您的时钟源是什么?

    您是否正在使用 C2000Ware 示例并更改计时器值? 是否使用最新的 C2000Ware driverlib 代码捕获上述图?

    我可以尝试复制您的配置、看看我是否可以与您的发现相关联。 请将您对 C2000Ware driverlib 示例所做的更改发送给我吗?

    此致、

    Nirav

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

    Nirav、您好!

    我正在使用 Device_init()函数中的默认时钟配置,该函数从 INTOSC2获取时钟源,并以100MHz 的频率运行。

    对于实际的计时器配置、我从一个空的 C2000Ware 示例开始、并参考技术参考手册、使用寄存器级代码而不是 driverlib 函数。

    非常感谢您提供重复配置。 我已附加我的 CCS 工程的 zip 文件。 它具有器件支持和 driverlib 文件的本地副本、因此我想您可以在几乎没有调整的情况下运行它。 在本示例中、我将切换 GPIO6。

    如果您发现任何问题、请告诉我。 再次感谢。

    此致、

    Vishnu

    e2e.ti.com/.../f28002x_5F00_timer.zip 

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

    谢谢 Vishnu。 我还建议您使用 C2000Ware 示例、如果您尚未尝试过、请在此期间尝试您的配置。 C2000Ware 示例经过验证、因此最好使用它们。

    此致、

    Nirav