工具与软件:
大家好!
我在尝试根据 GPIO 信号使计时器启动和停止时卡住了。
我找不到任何示例、我曾尝试使用手册来实施、但没有任何效果。
您能帮我讲一讲一些示例代码吗?
基本上、我需要定时器在 FREE_RUN 模式下从 GPIOX 的 POS_EDGE 信号启动和从 GPIOY 的 POS_EDGE 信号停止。
目标是对 GPIOX 和 GPIOY 上事件之间的间隔内的定时器节拍进行计数。
提前感谢您!
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.
工具与软件:
大家好!
我在尝试根据 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!
事实证明、有时计数器的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:
我有两个想法:
此致、
Ryan