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.

[参考译文] TM4C1294NCPDT:用于获取频率的定时器捕捉模式

Guru**** 2595805 points


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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/740189/tm4c1294ncpdt-timer-capture-mode-to-get-frequency

器件型号:TM4C1294NCPDT

你好  

我正在尝试 使用计时器捕获模式计算输入信号的频率。

但是它运行良好,但有时结果会得到0值。

这怎么可能发生?

如何 消除 此误差?

#include 
#include 
#include "inc/hw_ints.h"
#include "inc/hw_types.h"
#include "inc/hw_memmap.h"
#include "driverlib/gpio.h"
#include "driverlib/fpu.h"
#include "driverlib/interrupt.h"

#include "driverlib/pin_map.h"





;include "driveript=idt.id小时#id小时#idr32=u.id小时#idr.id小时";

include "idridr.idr.idr.idr.u.idu.idr.idr.id小时#include "u.idr32";include "u.idr.idr.idr.idr.idr.idr.idr.idr.idr.idr.idr.idr.idr.idr.idr.idr.idr.idr.idr.idr.idr.idr.idr.idr.idr.

void
SysTickIntHandler (void)
{
//
//更新 SysTick 中断计数器。
//
if (g_ui32Counter>10000000){
G_ui32Counter=0;}
G_ui32Counter++;


}

void
InitConsole (void)
{

SysCtlPeripheralEnable (SYSCTL_Periph_GPIOA);
GPIOPinConfigure (GPIO_PA0_U0RX);
GPIOPinConfigure (GPIO_PA1_U0TX);
SysCtlPeripheralEnable (SYSCTL_Periph_UART0);
UARTClockSourceSet (UART0_BASE、UART_CLOCK_PIOSC);
GPIOPinTypeUART (GPIO_Porta_base、GPIO_PIN_0 | GPIO_PIN_1);
UARTStdioConfig (0、115200、16000000);
}
void EDGE_CAPTURE (void)
{
TimerIntClear (Timer1_base、timer_CAPB_event);
if (flag==false){
START = TimerValueGet (Timer1_base、timer_B);
flag=true;
}
如果(flag=true){
end = TimerValueGet (Timer1_base、timer_B);
时间=结束-开始;
flag=false;
TimerLoadSet (Timer1_base、timer_B、(10000-1));

}

void Configure_timer (void)
{
SysCtlPeripheralEnable (SYSCTL_Periph_GPIOD);
SysCtlPeripheralEnable (SYSCTL_Periph_Timer1);
GPIOPinTypeTimer (GPIO_PORTD_base、GPIO_PIN_3);
GPIOPinConfigure (GPIO_PD3_T1CCP1);
TimerConfigure (Timer1_base、(TIMER_CFG_SPLIT_PAIR | TIMER_CFG_B_CAP_TIME_UP));
TimerControlEvent (Timer1_base、timer_B、timer_event_POS_EDGE);
TimerPrescaleSet (Timer1_base、timer_B、(120-1));
TimerLoadSet (Timer1_base、timer_B、(10000-1));
内部寄存器(INT_TIMER1B、EDGE_CAPTURE);
TimerIntClear (Timer1_base、timer_CAPB_event);
TimerIntEnable (Timer1_base、timer_CAPB_EVENT);
IntEnable (INT_TIMER1B);
TimerEnable (Timer1_base、timer_B);
}

int main (void)
{
FPULazyStackingEnable();
ui32SysClock = SysCtlClockFreqSet ((SYSCTL_XTAL_25MHz |
SYSCTL_OSC_MAIN |
SYSCTL_USE_PLL|SYSCTL_CFG_VCO_480)、120000000);
InitConsole();
CONFIG_TIMER ();
SysTickPeriodSet (ui32SysClock/1000000);
IntMasterEnable();
SysTickIntEnable();
SysTickEnable();
while (1)
{
if (time!=0)
{
calc_freq();
}
}
}
void calc_freq (void)
{
float y;
y=time/1200;
y=1/y;
time=100000 *y;
UARTprintf ("开始:%d\n"、time);
时间=0;
结束=0;
开始=0;
}

 

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好!
    输入信号的速度有多快? 如果您的信号太快、则可能无法正确捕获时间。 例如、如果定时器检测到一个边沿、它将捕获一个 X 的定时器值。然后它将生成一个中断。 但是、CPU 需要一些时间(大约12个周期)才能进入中断 ISR、一旦进入 ISR 内部、就需要执行一些指令。 与您的情况一样、它需要清除状态寄存器、并在调用 TimerValueGet 之前确定该标志是真还是假。 如果您的下一个边沿过快、则可能是定时器已保存下一个定时器值(我们将其称为 Y)、从而覆盖了上一个 X 值。 在您调用 TimerValueGet 时、它已从 X 更改为 Y。因此、您的开始和结束都可以是 Y、差异将为零。

    如果您有快速信号、您可能需要考虑将该输入路由到两个不同的计时器模块。 在这种方法中、您可以获取两个不同计时器模块中两个不同计时器值之间的差异。 例如、使用计时器 A 记录开始时间、使用计时器 B 记录结束时间、并获取两者之间的差异。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    是、或者可能太小、我在30kHz 至1kHz 范围内对其进行测试