TI E2E™ 设计支持论坛将于 5 月 30 日至 6 月 1 日进行维护。如果您在此期间需要技术支持,请联系 TI 的客户支持中心寻求帮助。

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.

[参考译文] TM4C123GH6PGE:使用输入捕捉模式的 TimerValueGet ()在 OS 任务延迟下是不准确的。

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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1106012/tm4c123gh6pge-timervalueget-using-input-capture-mode-is-not-accurate-with-os-task-delay

器件型号:TM4C123GH6PGE

您好!

我正在使用 FreeRTOS 开发 TM4C123GH launchpad。

我在50Hz 至400Hz 之间有一个方波输入进入 PC7。 我已将计时器计数配置为递减、根据以下代码捕获每个上升沿的计时器:

Fullscreen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/* Enable the Timer
* Note that the GP Timer module clock must be enabled before the registers can be programmed
* (see page 338 or page 357). There must be a delay of 3 system clocks after the Timer module clock
* is enabled before any Timer module registers are accessed.
*/
MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_WTIMER1);
// Set the IO pin to be an input for wide timer
// Use PC7 which is input 8, which is an ODD input (i.e. TIMER B)
GPIOPinConfigure(GPIO_PC7_WT1CCP1);
MAP_GPIOPinTypeTimer(GPIO_PORTC_BASE, GPIO_PIN_7);
// Configure the timer
// Capture the time value at each event edge
MAP_TimerConfigure(WTIMER1_BASE, (TIMER_CFG_SPLIT_PAIR | TIMER_CFG_A_PERIODIC | TIMER_CFG_B_CAP_TIME));
// Count on Positive Edges
MAP_TimerControlEvent(WTIMER1_BASE, TIMER_B, TIMER_EVENT_POS_EDGE);
// The timer starts at 0xFFFFFFFF and counts down.
MAP_TimerLoadSet(WTIMER1_BASE, TIMER_B, 0x00FFFFFF);
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

我还有一个主要任务、在该任务中、我检查是否发生了捕获事件、读取计时器并计算差异、如下所示:

Fullscreen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
while(1)
{
// Check if we have status
/* Poll the CnERIS bit in the GPTMRIS register or wait for the interrupt to be generated (if enabled).
* In both cases, the status flags are cleared by writing a 1 to the CnECINT bit of the GPTM
* Interrupt Clear (GPTMICR) register. The time at which the event happened can be obtained
* by reading the GPTM Timer n (GPTMTnR) register.
*/
u32Status = MAP_TimerIntStatus(WTIMER1_BASE, 0);
if((u32Status & TIMER_CAPB_EVENT) == TIMER_CAPB_EVENT)
{
// Count of timer ticks between pulses
m_u32RawCount = (Luint32)TimerValueGet(WTIMER1_BASE, TIMER_B);
// As we are counting down do the difference
// It may be that the variant of the CPU we use does not have an up-counter function?
u32Diff = (0xFFFFFFFF - m_u32RawCount);
// Work out the difference
m_u32TimerCount = u32Diff - u32TempPrev;
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

我们注意到、如果频率为50Hz、则计时器值始终是合理的、但是一旦我们开始超过100Hz、对操作系统任务延迟值的任何更改(例如从1ms 到10ms)都会影响我们从计时器读取的值。 这种影响是半随机的、但是定时器值似乎 在正确的值和大约1/2的预期值之间交替。

我的理解 是发生捕获事件、自由运行定时器的值被传输到定时器值寄存器中、我们随后在未来的某个时候读取该寄存器。

有人能推测我们调用 TimerValueGet ()的速度为何会影响计时器值的准确性?

谢谢。

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

    在100Hz 时、每10ms 发生一次事件。 如果你停止寻找10ms、很有可能在那个时间发生两个事件、你将错过第一个事件;在这种情况下、算术将指示一个周期的长度是时间的两倍(速度的一半)。

    我建议使用 ISR 来馈送队列。 这样、您就不必猜测投票的频率。

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

    您好!

    在编写本文档时、我认为我看到了逻辑、如果我错过了一个计时器事件、那么上一个事件和下一个采样事件之间的差异将是时间的两倍。

    谢谢!