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.

[参考译文] CC2652R7:将 GPIOTimer 设置为通过 GPIO 边沿启动和停止

Guru**** 2393725 points
Other Parts Discussed in Thread: CC2652R7

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

https://e2e.ti.com/support/wireless-connectivity/other-wireless-group/other-wireless/f/other-wireless-technologies-forum/1461786/cc2652r7-setting-up-gpiotimer-to-start-and-stop-by-gpio-edges

器件型号:CC2652R7

工具与软件:

大家好!

我在尝试根据 GPIO 信号使计时器启动和停止时卡住了。

我找不到任何示例、我曾尝试使用手册来实施、但没有任何效果。

您能帮我讲一讲一些示例代码吗?

基本上、我需要定时器在 FREE_RUN 模式下从 GPIOX 的 POS_EDGE 信号启动和从 GPIOY 的 POS_EDGE 信号停止。

目标是对 GPIOX 和 GPIOY 上事件之间的间隔内的定时器节拍进行计数。

提前感谢您!

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

    尊敬的 Ashot:

    到目前为止、您尝试了哪些方法、哪些方法无法满足您的期望?  有多个计时器选项、包括 GPTimer (不是首选、因为它禁止待机低功耗模式)、 ClockP (首选选项)和 TimestampP。  您是否正在使用 GPIO 而不是 按钮 驱动程序?  请确保您的信号没有反弹/振荡、从而将中断处理两次。  以下是 SimpleLink F2 SDK 中提供的 CC2652R7的示例。

    此致、
    Ryan

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

    Ryan、感谢您的反馈。

    我的任务是对 GPIO 上两个事件之间的计时器节拍数进行计数。

    我可以使用标准方法来处理、例如启动计时器、停止计时器和检索计时器计数。

    但是、配置定时器以便之后、Timer_Start它开始在一个 GPIO 中的事件上递增计数、而在另一个 GPIO 中的事件上停止递增计数、这是我所无法实现的。

    很遗憾、我也找不到手册、示例或在线资源中的任何示例或指南。

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

    尊敬的 Ashot:

    我可能误解了你的意图。  我最初以为您会使用 GPIO 中断和计时器 API 来停止/启动/收集计时器。  如果您希望 自动计算 GPIO 边沿之间的时间、而不进行任何应用程序函数调用、则需要利用 Event 和 IOC driverlib 函数来实现。  以下是一些帮助您入门的建议。

    遗憾的是、TI 没有提供类似的示例代码可帮助实现这一目的、但您也可以参阅 每个模块的寄存器说明以了解更多详细信息。  如果您的应用允许、那么利用应用的硬件中断处理程序内的 GPIO 中断会容易得多。

    此致、
    Ryan

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

    谢谢、Ryan! 我会尽快尝试

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

    尊敬的 Ryan:

    似乎我成功了。

    目前、我在超级循环中使用脉冲生成。

    其中一个日子,我将尝试制造一个外部发电机,以确保测量稳定。

    我将写下有关结果的信息。

    感谢您发送编修。

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

    您好、Ryan!

    事实证明、有时计数器的16位值对我而言是不够的。

    我将两个单独的计时器 GPT0和 GPT2配置为24位模式。  

    同时、我对其进行配置、以便一个由脉冲 A 的负边沿触发、另一个由脉冲 B 的负边沿触发

    在边线之间的较长间隔下、一切看起来都很好。

    但出于某种原因、在短时间间隔内、GPT0  的时间比 GPT2早28个周期。

    下面是设置为500MSPS 的逻辑分析仪的屏幕截图:

    下面是一个代码片段:

    #include <ti/drivers/GPIO.h>
    #include <ti/drivers/UART2.h>
    #include <ti/drivers/gpio/GPIOCC26XX.h>
    #include <ti/drivers/Timer.h>
    #include <ti/drivers/timer/GPTimerCC26XX.h>
    #include <ti/drivers/Board.h>
    #include <ti/drivers/power/PowerCC26XX.h>
    #include <ti/devices/DeviceFamily.h>
    #include DeviceFamily_constructPath(driverlib/event.h)
    #include DeviceFamily_constructPath(driverlib/timer.h)
    
    ....
    
    // IRQ callbacks
    static void TimerAIsr(UArg arg) {
        TimerIntClear(GPT0_BASE, TIMER_CAPA_EVENT);
    }
    
    
    static void TimerBIsr(UArg arg) {
        TimerIntClear(GPT2_BASE, TIMER_CAPA_EVENT);
        Semaphore_post(UARTAccessSemHandle);
    }
    
    ......
    
    
    static uint32_t ticks0, ticks1;
    
    void *mainThread(void *arg0) {
    
        ....
    
    
        HWREG(IOC_BASE + IOC_O_IOCFG14) |= (IOC_IOCFG14_EDGE_DET_NEG | IOC_IOCFG14_PORT_ID_PORT_EVENT1);    // BUTTON_0
        HWREG(IOC_BASE + IOC_O_IOCFG13) |= (IOC_IOCFG13_EDGE_DET_NEG | IOC_IOCFG13_PORT_ID_PORT_EVENT5);    // BUTTON_1
    
        // Set EVENT0 and EVENT1 to trigger the edge capture of the GP timers.
        HWREG(EVENT_BASE + EVENT_O_GPT0ACAPTSEL) = EVENT_GPT0ACAPTSEL_EV_PORT_EVENT1;   // Timer_A EVENT
        HWREG(EVENT_BASE + EVENT_O_GPT2ACAPTSEL) = EVENT_GPT2ACAPTSEL_EV_PORT_EVENT5;   // Timer_B EVENT
    
        ....
    
    
        HWREG(GPT0_BASE + GPT_O_SYNC) = GPT_SYNC_SYNC0_TIMERA | GPT_SYNC_SYNC2_TIMERA;
    
        // Enable both timers
        TimerEnable(GPT0_BASE, TIMER_A);
        TimerEnable(GPT2_BASE, TIMER_A);
    
        Hwi_enableInterrupt(INT_GPT0A);
        Hwi_enableInterrupt(INT_GPT2A);
    
    
        while (1) {
            Semaphore_pend(UARTAccessSemHandle, BIOS_WAIT_FOREVER);
            ticks0 = TimerValueGet(GPT0_BASE, TIMER_A);
            ticks1 = TimerValueGet(GPT2_BASE, TIMER_A);
            GPIO_toggle(RED_LED);
    
            if (ticks0 > ticks1) {
                len = snprintf(buf, sizeof(buf), "T0 %10lu > T2 %10lu\t%10ld\r\n", ticks0, ticks1, (int32_t) ticks1 - ticks0);
            } else {
                len = snprintf(buf, sizeof(buf), "T0 %10lu < T2 %10lu\t%10ld\r\n", ticks0, ticks1, (int32_t) ticks1 - ticks0);
            }
            UART2_write(debugUART, buf, len, &bytesWritten);
        }
    

    下面是一个日志结果:

    T0 16270504 > T2 16270476 -28
    T0 13048956 > T2 13048928 -28
    T0 9826008 > T2 9825980 -28
    T0 6603500 > T2 6603473 -27
    T0 3380429 > T2 3380401 -28

    同时、使用相同的逻辑分析器、我确保 TimerIsr 始终在 TimerIsr 之前触发。

    但是、TimerValueGet 函数返回的 T2时间滞后于 T0。

    在16位模式下、我不会观察到这样的效果、 即使脉冲 A 和脉冲 B 边沿之间的距离小于300纳秒、T2也始终大于 T0。

    如何解释 CAP_TIME_UP 模式下的24位 GPT 的这种行为?

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

    尊敬的 Ashot:

    我有两个想法:

    1. 如果 TimerBISOR 事件在 TimerAIsr 完成 TimerIntClear (GPT0_BASE、TIMER_CAPA_EVENT)之前触发 、则服务 TimerIntClear (GPT2_BASE、TIMER_CAPA_EVENT)将出现延迟;因此、对相邻中断事件的精确计时能力将受到限制。  如果不进一步深入了解计时器寄存器设置、则不会解释16位和24位模式之间观察到的差异。
    2. TimerValueGet 只读取 TAR 寄存器、但在24位模式下、您还需要考虑 TAPR、或 TimerPrescaleValueGet。  尽管这不会对所描述的行为产生任何影响、但最好注意如何在代码中计入24位计时器。

    GPT0寄存器

    此致、
    Ryan