您好!
我正在使用 FreeRTOS 开发 TM4C123GH launchpad。
我在50Hz 至400Hz 之间有一个方波输入进入 PC7。 我已将计时器计数配置为递减、根据以下代码捕获每个上升沿的计时器:
/* 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); MAP_TimerMatchSet(WTIMER1_BASE, TIMER_B, 0x00FFFFFE); // Configure the prescaler // Note: I can not see when this is operating in our split timer mode MAP_TimerPrescaleSet(WTIMER1_BASE, TIMER_B, 0xFF); MAP_TimerPrescaleMatchSet(WTIMER1_BASE, TIMER_B, 0xFE); // Configure the update mode TimerUpdateMode(WTIMER1_BASE, TIMER_B, TIMER_UP_LOAD_IMMEDIATE); // Clear the interrupt for TIMER_B capture event MAP_TimerIntClear(WTIMER1_BASE, TIMER_CAPB_EVENT); // Start the timer MAP_TimerEnable(WTIMER1_BASE, TIMER_B);
我还有一个主要任务、在该任务中、我检查是否发生了捕获事件、读取计时器并计算差异、如下所示:
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; // Save the prev value u32TempPrev = u32Diff; // Clear the flag again for next time MAP_TimerIntClear(WTIMER1_BASE, TIMER_CAPB_EVENT); } vTaskDelay(pdMS_TO_TICKS(1)); }
我们注意到、如果频率为50Hz、则计时器值始终是合理的、但是一旦我们开始超过100Hz、对操作系统任务延迟值的任何更改(例如从1ms 到10ms)都会影响我们从计时器读取的值。 这种影响是半随机的、但是定时器值似乎 在正确的值和大约1/2的预期值之间交替。
我的理解 是发生捕获事件、自由运行定时器的值被传输到定时器值寄存器中、我们随后在未来的某个时候读取该寄存器。
有人能推测我们调用 TimerValueGet ()的速度为何会影响计时器值的准确性?
谢谢。