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.

Input edge counting with TM4C123GH6PM



Hi!

I'm currently working on a simple frequency counter which should count positive edges within a second wide timegate. The time gate signal is coming from an external device and triggers a gpio interrupt which is just working fine. The external edges are produced by the PWM0 module and teh frequency is between 11 and 12 Hz.


I configured wide timer #3 as an input edge counter. I'm a bit confused here but my idea is to read the timer value (the counted edges) using the TimerValueGet(...) function of TIVAWare in the 1 sec interrupt handler:

* readout timer value (edge count in this mode)

*edges = timer value - previous timer value

*previous timer value = timer value 

I'm always getting zeroes here so I tried just to check out the timer value which gives me 0x000000FF and slowly decrementing by one after every 21 sec. Here is my code:

void Init_Capture_Timer(void){

	/*
	 * Enable Capture Timer peripherial
	 */
	SysCtlPeripheralEnable(CAPTURE_TIMER_PH);

	/*
	 * Configure 24 bit capture timer
	 */
	TimerConfigure(CAPTURE_TIMER_BASE, (TIMER_CFG_SPLIT_PAIR | TIMER_CFG_A_CAP_COUNT));

	/*
	 * Capture on positive edges
	 */
	TimerControlEvent(CAPTURE_TIMER_BASE, TIMER_A, TIMER_EVENT_POS_EDGE);


	/*
	 * Load and Match registers
	 */
	TimerLoadSet(CAPTURE_TIMER_BASE, TIMER_A, 0xFFFF);
	TimerMatchSet(CAPTURE_TIMER_BASE, TIMER_A, 0);
	/*
	 * Setup the interrupts for the timer timeouts.
	 */
	//IntEnable(CAPTURE_TIMERA_INT);
	//TimerIntEnable(CAPTURE_TIMER_BASE,  TIMER_CAPA_MATCH);

}

void Enable_Capture_Timer(void){

	TimerEnable(CAPTURE_TIMER_BASE, TIMER_A);
}

 

 

  • Hi,

    The user manual states the followings:

    During initialization in down-­count mode, the GPTMTnMATCHR and GPTMTnPMR registers are configured so that the difference between the value in the GPTMTnILR and GPTMTnPR registers and the GPTMTnMATCHR and GPTMTnPMR registers equals the number of edge events that must be counted.  

    So it seems to me that this mode is not suitable for your application, since the exact number of edge events must be known before - your application needs to manage a free number of events, unknown, and and start/stop cumulation of events would be better. 

    I would use a GPIO interrupt on input pin and simply increment a counting variable in interrupt routine, and start/stop managed by a timer duration.

    Petrei


  • Hi Petrei,

    in the meantime I think I got this thing working. There were a couple of errors, in fact. Firstly, the result was to send over by UART and this function had a minor flaw so it was sending wrong values.
    After that, when down counting, you need to re-enable the timer when the match value is reached otherwise it wont count any more edges. It is better to use up counter since it never stops counting.
    Secondly, at higher frequencies you need to configure the full-width counter.

    So far I was able to measure an 5 MHz signal which was my actual aim. Your approach is also good but I find mine better as there is a dedicated hardware which does the counting and doesn't fire interrupts all the time.

    The bit you quoted from the manual is about using match count interrupts - I'm not using that (it is commented out in my code.) 

  • Great Greg. Mind to share?
  • Dear JustGreg,

    I want to count 1 MHz using TM4c129 timer in edge counting mode. You already have achieved 5 MHz. Can you please share code, for initialization and reading. I am getting zero all the time.

    my init routine is as under

    ROM_TimerDisable(TIMER2_BASE, TIMER_A);
    ROM_TimerDisable(TIMER2_BASE, TIMER_B);
    HWREG(TIMER2_BASE)=0x04; //Edge count mode
    HWREG(TIMER2_BASE+0x04)=0x13; //AMR -Counter A Count up in edge count mode -
    HWREG(TIMER2_BASE+0x08)=0x13; //BMR -Counter B Count up in edge count mode
    HWREG(TIMER2_BASE+0x0C)=0x00; //A & B Both rising edge Counting

    HWREG(TIMER2_BASE+0x38)=0x00; //A Load Prescaler to Zero
    HWREG(TIMER2_BASE+0x3C)=0x00; //B Load Prescaler to Zero
    ROM_TimerEnable(TIMER2_BASE, TIMER_A);
    ROM_TimerEnable(TIMER2_BASE, TIMER_B);

    Every second I am reading counts by

    TimerACounts = HWREG(TIMER2_BASE+0x048) & 0xFFFFFF;