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.

[参考译文] TMS320F28P650DK:如何将计时器周期设置为100ns?

Guru**** 2540720 points


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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1402987/tms320f28p650dk-how-do-i-set-the-timer-period-to-100ns

器件型号:TMS320F28P650DK

工具与软件:

大家好!


如何更改计时器周期以每100ns 获得计时器中断?

不幸的是、我只能设置最小值2us。

我的当前代码:

//#############################################################################
//
// FILE:   timer_ex1_cputimers.c

//
// Included Files
//
#include "driverlib.h"
#include "device.h"

//
// Function Prototypes
//
__interrupt void cpuTimer0ISR(void);
void initCPUTimers(void);
void configCPUTimer(uint32_t, float, float);

//
// Main
//
void main(void)
{
    //
    // Initializes device clock and peripherals
    //
    Device_init();

    Device_initGPIO();

    //
    // Initializes PIE and clears PIE registers. Disables CPU interrupts.
    //
    Interrupt_initModule();

    //
    // Initializes the PIE vector table with pointers to the shell Interrupt
    // Service Routines (ISR).
    //
    Interrupt_initVectorTable();

    //
    // ISRs for each CPU Timer interrupt
    //
    Interrupt_register(INT_TIMER0, &cpuTimer0ISR);

    //
    // Initializes the Device Peripheral. For this example, only initialize the
    // Cpu Timers.
    //
    initCPUTimers();

    //
    // Configure CPU-Timer 0 to interrupt every ... seconds:
    // 1 Period respectively (in uSeconds)
    //
    configCPUTimer(CPUTIMER0_BASE, DEVICE_SYSCLK_FREQ, 0.2);

    //
    // To ensure precise timing, use write-only instructions to write to the
    // entire register. Therefore, if any of the configuration bits are changed
    // in configCPUTimer and initCPUTimers, the below settings must also
    // be updated.
    //
    CPUTimer_enableInterrupt(CPUTIMER0_BASE);

    //
    // Enables CPU int1 which are connected to CPU-Timer 0, respectively.
    // Enable TINT0 in the PIE: Group 1 interrupt 7
    //
    Interrupt_enable(INT_TIMER0);

    //
    // Starts CPU-Timer 0.
    //
    CPUTimer_startTimer(CPUTIMER0_BASE);

    //
    // Enable Global Interrupt (INTM) and realtime interrupt (DBGM)
    //
    EINT;
    ERTM;

    GPIO_writePin(0, 1);
    GPIO_setPinConfig(GPIO_0_GPIO0);
    GPIO_setDirectionMode(0, GPIO_DIR_MODE_OUT);

    //
    // IDLE loop. Just sit and loop forever (optional)
    //
    while (1)
    {
    }
}

//
// initCPUTimers - This function initializes all three CPU timers
// to a known state.
//
void initCPUTimers(void)
{
    //
    // Initialize timer period to maximum
    //
    CPUTimer_setPeriod(CPUTIMER0_BASE, 0xFFFFFFFF);

    //
    // Initialize pre-scale counter to divide by 1 (SYSCLKOUT)
    //
    CPUTimer_setPreScaler(CPUTIMER0_BASE, 0);

    //
    // Make sure timer is stopped
    //
    CPUTimer_stopTimer(CPUTIMER0_BASE);

    //
    // Reload all counter register with period value
    //
    CPUTimer_reloadTimerCounter(CPUTIMER0_BASE);


}

//
// configCPUTimer - This function initializes the selected timer to the
// period specified by the "freq" and "period" parameters. The "freq" is
// entered as Hz and the period in uSeconds. The timer is held in the stopped
// state after configuration.
//
void configCPUTimer(uint32_t cpuTimer, float freq, float period)
{
    uint32_t temp;

    //
    // Initialize timer period:
    //
    temp = (uint32_t) ((freq / 1000000) * period);
    CPUTimer_setPeriod(cpuTimer, temp - 1);

    //
    // Set pre-scale counter to divide by 1 (SYSCLKOUT):
    //
    CPUTimer_setPreScaler(cpuTimer, 0);

    //
    // Initializes timer control register. The timer is stopped, reloaded,
    // free run disabled, and interrupt enabled.
    // Additionally, the free and soft bits are set
    //
    CPUTimer_stopTimer(cpuTimer);
    CPUTimer_reloadTimerCounter(cpuTimer);
    CPUTimer_setEmulationMode(cpuTimer,
                              CPUTIMER_EMULATIONMODE_STOPAFTERNEXTDECREMENT);
    CPUTimer_enableInterrupt(cpuTimer);

}

//
// cpuTimer0ISR
//
__interrupt void cpuTimer0ISR(void)
{
    GPIO_writePin(0, 1);
    GPIO_writePin(0, 0);

    //
    // Acknowledge this interrupt to receive more interrupts from group 1
    //
    Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP1);
}



//
// End of File
//


此致

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

    您好!

    该频率应该可以使用此器件上的 CPU 计时器模块实现。  

    如果你调用  configCPUTimer()函数并传递一个0.2周期值(如你所示)、这将导致每0.2 us 产生一个中断:

    0.0000002us = 0.0002ms = 0.2us = 200ns

    要实现每100 ns 的 CPU 计时器中断、应将0.1传递到  configCPUTimer()函数中。 如果在传递该值时遇到任何问题、请告诉我。 最好使用在每个 CPU 计时器 ISR 中切换的 GPIO 在示波器上验证所实现的频率。

    此致、

    Delaney

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

    不幸的是、如果我指定较小的周期、它将不起作用。 我突然不再测量信号

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

    您好!

    很抱歉耽误你的时间。 如果您使用0.1的值来单步执行配置代码、您是否看到 CPU 计时器寄存器在表达式视图中写入了正确的值? 你还可以尝试在 ISR 中放置一个断点、并查看 CCS 调试器是否遇到过断点吗?

    此致、

    Delaney

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

    您好!
    在哪个寄存器中应该是哪个值? (不幸的是、我错误地单击了"这解决了我的问题")

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

    您好!

    对于100ns 周期和200MHz 的 SYSCLK:

    - SYSCLK 将每5ns = 5 x (10^-9)秒进行一次滴答

    - 100ns/5ns = 20、因此每200ns 需要20个 SYSCLK 周期才能实现一次中断

    因此、您可以验证 PRD 寄存器写入的值为20 (LSW 应为0x14、MSW 应为0x00)。 如果您看到不同的值、请附上所有计时器计数器寄存器值的屏幕截图。

    此致、

    Delaney