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.

TM4C129DNCPDT: TM4C129dncpdt frequency measurement problem

Part Number: TM4C129DNCPDT

Hi,

I am trying to measure the frequency.

Range: Up to 12mHz

I have tried 3 method

1. FW polling the input gpio pin, count the clock, this way can measure about 5~6 mHz frequency input.

2.Set gpio as interrupt, when the frequency over 2mHz, system hang.

3.Use ccp pin and timer to count the clock, it is good from 100~2.1mHz

   When the input frequency over 2.2mHz, the counter didn't work.

   Return value from  TimerValueGet(TIMER3_BASE, TIMER_A) didn't come down.

   System clock is 120mHz

   Could someone give any advice for this?

uint32_t elapsedHi_us, elapsedLoStart_us, elapsedLoEnd_us;
uint32_t nStopTime_us, nCycCount = 0;
SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER3);
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);
Wait(10);
GPIOPinConfigure(GPIO_PD4_T3CCP0);
GPIOPinTypeTimer(GPIO_PORTD_BASE, GPIO_PIN_4); // PD4

TimerDisable(TIMER3_BASE, TIMER_A);
TimerConfigure(TIMER3_BASE, TIMER_CFG_SPLIT_PAIR|TIMER_CFG_A_CAP_COUNT);
TimerControlEvent(TIMER3_BASE,TIMER_A,TIMER_EVENT_POS_EDGE);
TimerLoadSet(TIMER3_BASE, TIMER_A, 65000);
TimerMatchSet(TIMER3_BASE, TIMER_A, 0);
TimerLoadSet(TIMER3_BASE, TIMER_A, 65000);

ROM_IntMasterDisable();


SysTimeStamp* pTs = SysTimeStamp::GetPtr();
pTs->Reset();

pTs->GetTimeStamp( &elapsedHi_us, &elapsedLoStart_us );

TimerEnable(TIMER3_BASE, TIMER_A);

do
{
    pTs->GetTimeStamp( &elapsedHi_us, &elapsedLoEnd_us );
}while((elapsedLoEnd_us-elapsedLoStart_us)<10001);     // 10ms

nCycCount = TimerValueGet(TIMER3_BASE, TIMER_A);

nCycCount = (uint32_t)65000 - nCycCount;
TimerDisable(TIMER3_BASE, TIMER_A);

ROM_IntMasterEnable();
*freq = nCycCount*100;

  • Take a look at the datasheet and see if the timer an be configured to count on external clock sources.

    If not, you may have to use input capture. To the extend possible, use the highest value Prescaler - it does sacrifice resolution.

    Configure the timer as free running, top at 0xffff. Zero the counter at beginning of the process and wait for a set period of time to pass. And then read the input capture counter - you. Can convert it to its frequency equivalent.

  • I would first - prior to any change - measure the arrival of your input signal, "At the MCU's CCP pin."    (and measured ONLY at that pin!)  

    Are you providing a good square wave - free from transient (edge) signal spikes - and w/in the MCU's  "0V - 3V3" signal input range?    (Be sure to SCOPE your signal at its higher (Failing) frequency!)    Is the ground between your (assumed) signal source - and your MCU - robust & solid?   Really?

    The "System Hang" you report  IS  unexpected - and concerning.    I don't know if  "System Hang" provides a, "universally known" meaning - but I don't believe it proves as clear as it (could) or should be.

    Limited facts lead me to (somewhat) believe that your Timer's ISR, "Takes too long to complete" - which directly impacts your,  "Top Measurement Frequency."    Two "Toggle Led" functions - placed at the "Top & Bottom" of your Timer ISR - should enable eased measurement of the ISR's duration.    (ISR's most always should be,  "Short & Sweet" - Do the "Dirty Work" elsewhere!)

    If the guidance above proves (both) well measured & true - I would choose your Timer's  "Edge Counter Mode"  and employ the following:

    • Disable your chosen, 32-bit Timer  (We'll label this Timer 1)
    • Order it into,  "Edge Count Mode"
    • Clear the appropriate Timer Register (Timer 1) which, "Accumulates such external signal arrivals/counts"
    • Employ a 2nd,  32-bit Timer - this one ordered into "One-Shot" Mode.    This 2nd Timer will create the,  "Duration Window" - of Timer "1's" signal capture

    Note that the MCU - when in Timer Mode - may  (properly) respond to  external signals - "Not Faster" than 1/4th the System Clock.    (assumed 120MHz/4 = 30MHz - your case)

    Now a 32-bit counter - starting from zero - may reach to 4.294 billion counts w/in 1 Second.    A suitable timebase may be 1/8th of a Second - which would require the value, "536,870,912" to be loaded into your Timer 2 (the One-Shot) Timer.

    With the above - accomplished, tested/measured, and ready"

    • Enable (both) the "One-Shot" (Timer 2) and "Edge Count" (Timer 1) timers.    Both should "Start their processes - ideally in unison" but even a (slight) delay will not prove of consequence.
    • Upon "Expiration" of the "One-Shot" (Timer 2) immediately (if not sooner) Disable the "Edge Count" (Timer 1).
    • Should the "Edge-Count Timer" have been enabled - with its Accumulating Register Cleared - and configured to "Up Count" - the register content should reflect 1/8th of the input signal's frequency.

    To "Test/Verify" - with a 20MHz (safe, MCU compliant) input frequency - and employing the 1/8 Second - Input Signal, Edge Count Gating - the value 2,500,000 should have been captured w/in the Edge-Count Timer.   (Timer 1)  

    Note that this is an "On-Going" repetitive process - and if a 1/8th Second Update Interval is NOT required - you may  "increase measurement accuracy"  by averaging  four or eight measurements - prior to displaying the results.

    Having past worked in the "Display Field" - updating a display at 1/2 of the 1/8 Second interval (i.e. 1/4 Second) should be recognizable by most viewers.     (the use of any "Prescalar" - which was admitted to "compromise resolution" - appears without merit  & is NOT recommended...)

  • Hi cb1_mobile, 

    1. I use function generator to output square wave

    2. For interrupt method, my ISR only do GPIOIntClear and a value++

    Thanks,

    Light

  • Thank you, Mr. Hsieh. (BTW - I know (several) sharing your name)

    Please read again - I'm in a "weak signal zone" - and composed in pieces - so that (something) would "get thru." (maybe)

    Your function generator - minus a scope check - may be distorting and/or generating edge transients - harmful to the MCU. Scope check IS important - and "AT your HIGHEST FREQUENCY (where presently failing!)

    Your mention of  "So Little contained w/in your ISR" - presents an (unfortunate) irony!   (while proving my earlier "guess" incorrect.)

    MCU Manual and/or other vendor "docs" advise that the ISR must be "Cleared EARLY" - otherwise the process may not fully complete!    And you - with so SHORT an ISR - may "improperly clear - or even Fail to Clear" your ISR - due to,  "TOO FAST ISR EXECUTION!"    I'm uncertain - but you might try adding "some delay" between your ISR Clear - and the exit from the ISR - to determine if  "this may solve - an improper ISR Clear!"