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.

Timer counting accuracy via Wide Timer

Hello.

I am using WT5CCP1 to measure the frequency of a square signal comparing it with an internal Timer of 1 second in Wide Timer 4.

However, the value I get is higher than expected. For example, if I set up my signal generator at 200kHz, I get 205kHz

If I set up 50kHz I get 52kHz, and if I set up 30 kHz I get 31. The scope measures the expected frequency correctly, not the one the launchpad is reading.

Is there anything delaying the internal 1second timer? It happens the same even with a different internal 1 second Timer.


My inizialization code is as follows:


int32_t cuenta_interrupcion=1000;//Measuring  kHz
void init_WTIMER5_READ(void)
{
	MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_WTIMER5);
	// Enable port PD7 for WTIMER5 WT5CCP1
	// First open the lock and select the bits we want to modify in the GPIO commit register.
	//
	HWREG(GPIO_PORTD_BASE + GPIO_O_LOCK) = GPIO_LOCK_KEY;
	HWREG(GPIO_PORTD_BASE + GPIO_O_CR) = 0x80;

	//SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);
	MAP_GPIOPinConfigure(GPIO_PD7_WT5CCP1);
	MAP_GPIOPinTypeTimer(GPIO_PORTD_BASE, GPIO_PIN_7);

	//TimerConfigure(WTIMER5_BASE, TIMER_CFG_SPLIT_PAIR | TIMER_CFG_B_CAP_TIME);	    //Every edge
	TimerConfigure(WTIMER5_BASE, TIMER_CFG_SPLIT_PAIR | TIMER_CFG_B_CAP_COUNT_UP);//FUNCIONA!!!!

	

	// Freeze the timer counting if we are debugging (the counting is enabled automatically with the cpu).
	//TimerControlStall(WTIMER5_BASE, TIMER_B, true);

	 TimerControlEvent(WTIMER5_BASE,TIMER_B,TIMER_EVENT_POS_EDGE);



	    TimerLoadSet(WTIMER5_BASE, TIMER_B, cuenta_interrupcion+1);  // 1MHz OK
	    TimerMatchSet(WTIMER5_BASE,TIMER_B, cuenta_interrupcion+1);

	//TimerLoadSet(WTIMER5_BASE, TIMER_B, 1600);  //Count for 50KHz at 80MHz clock.
	//TimerMatchSet(WTIMER5_BASE, TIMER_B, 800);  //50% duty cycle at init


	//  TimerIntRegister(WTIMER5_BASE, TIMER_B, WTimer5BIntHandler);

	  // TimerIntEnable(WTIMER5_BASE, TIMER_CAPB_EVENT);//Every edge
	TimerIntEnable(WTIMER5_BASE, TIMER_CAPB_MATCH); //FUNCIONA!!
	TimerEnable(WTIMER5_BASE, TIMER_B);

	IntEnable(INT_WTIMER5B);

	
}


void InitTimer_1sec()
{//Timer 1 second

//SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER2);
ROM_SysCtlPeripheralEnable (SYSCTL_PERIPH_WTIMER4);
TimerConfigure(WTIMER4_BASE, TIMER_CFG_PERIODIC);
TimerLoadSet(WTIMER4_BASE, TIMER_A, ROM_SysCtlClockGet() );//Tried also with value: ROM_SysCtlClockGet() -1
IntEnable(INT_WTIMER4A);
TimerIntEnable(WTIMER4_BASE, TIMER_TIMA_TIMEOUT);
TimerEnable(WTIMER4_BASE, TIMER_A);
}


The interrrupt routines are:

void WTimer5BIntHandler(void)

{//COUNTER INTERRUPT



//TimerIntClear(WTIMER5_BASE, TIMER_CAPB_EVENT);//Para cada una
//TimerIntEnable(WTIMER5_BASE, TIMER_CAPB_MATCH); //FUNCIONA!!



cont_wTimer5B++;
cont_wTimer5B_periodo++;




TimerIntClear(WTIMER5_BASE, TIMER_CAPB_MATCH);




}

void WTimer4AIntHandler(void)
{//1second interrupt


//
// Clear the timer interrupt.
//

TimerIntClear(WTIMER4_BASE, TIMER_TIMA_TIMEOUT);



contador_pulsos_Hz=cont_wTimer5B_periodo;
cont_wTimer5B_periodo=0;


flag_print=true;


/* TimerLoadSet(WTIMER4_BASE, TIMER_A, ROM_SysCtlClockGet()-1 );
TimerEnable(WTIMER4_BASE, TIMER_A);/**/
}



In the while loop:

if (flag_print)
{
flag_print=false;
UARTprintf("FREQ: %d kHz ",contador_pulsos_Hz);

}



  • Any issue with the timers anybody?

  • PAk SY said:

    not the one the launchpad is reading.

    Mon ami - multiple launchpads exist - perhaps your identification of "MCU under test" would aid...  (our usage under LX4F - both wide & standard timers - reveals no such issue...)

    And - as you strive for accuracy - does not this usage rise in suspicion?

    TimerLoadSet(WTIMER4_BASE, TIMER_A, ROM_SysCtlClockGet() );

    Yes - some tell us here that this ROM version improves - yet cannot be too hard to calculate - replace this w/"calculated, hard value" - and see if issue departs...

    Update: Appears "temporary insanity" (my part) alive/well - this offering.  Managed to confuse, "ROM_SysCtlDelay()" w/above - in attempting to provide you some response/comfort.  (we have noted a lack of linearity - especially when relatively small values are "in play" - even w/heralded ROM version of SysCtlDelay().)

  • cb1_mobile said:

    not the one the launchpad is reading.

    Mon ami - multiple launchpads exist - perhaps your identification of "MCU under test" would aid...  (our usage under LX4F - both wide & standard timers - reveals no such issue...)

    [/quote]

    Since we are in Tiva forums, it is Tiva Launchpad.

    cb1_mobile said:

    And - as you strive for accuracy - does not this usage rise in suspicion?

    TimerLoadSet(WTIMER4_BASE, TIMER_A, ROM_SysCtlClockGet() );

    Yes - some tell us here that this ROM version improves - yet cannot be too hard to calculate - replace this w/"calculated, hard value" - and see if issue departs...

    Update: Appears "temporary insanity" (my part) alive/well - this offering.  Managed to confuse, "ROM_SysCtlDelay()" w/above - in attempting to provide you some response/comfort.  (we have noted a lack of linearity - especially when relatively small values are "in play" - even w/heralded ROM version of SysCtlDelay().)



    I can see your mistake is easy to do, they sound pretty much the same.

    Anyway, I tried and got the same values using both ROM_SysCtlClockGet and SysCtlClockGet so that is not the issue.

    What I found is that changind the board gave me different results (probably one was deflected) , and try to play with the units by playing with the value of cuenta_interrupcion variable in the code. It is supposed to change the magnitude of the counted frequency. However, with some values, the value is not accurated and with some others it is.

    For example, it is with 1000 and 1(multiplying by 2 the value cont_wTimer5B_periodo or contador_pulsos_Hz at the end), and it is not iwth 10 or 100.

    Actually, I do not see the issue.

    int32_t cuenta_interrupcion=1000;//Measuring  kHz
    void init_WTIMER5_READ(void)
    {
        MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_WTIMER5);
        // Enable port PD7 for WTIMER5 WT5CCP1
        // First open the lock and select the bits we want to modify in the GPIO commit register.
        //
        HWREG(GPIO_PORTD_BASE + GPIO_O_LOCK) = GPIO_LOCK_KEY;
        HWREG(GPIO_PORTD_BASE + GPIO_O_CR) = 0x80;
     
        //SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);
        MAP_GPIOPinConfigure(GPIO_PD7_WT5CCP1);
        MAP_GPIOPinTypeTimer(GPIO_PORTD_BASE, GPIO_PIN_7);
     
        //TimerConfigure(WTIMER5_BASE, TIMER_CFG_SPLIT_PAIR | TIMER_CFG_B_CAP_TIME);        //Every edge
        TimerConfigure(WTIMER5_BASE, TIMER_CFG_SPLIT_PAIR | TIMER_CFG_B_CAP_COUNT_UP);//FUNCIONA!!!!
     
         
     
        // Freeze the timer counting if we are debugging (the counting is enabled automatically with the cpu).
        //TimerControlStall(WTIMER5_BASE, TIMER_B, true);
     
         TimerControlEvent(WTIMER5_BASE,TIMER_B,TIMER_EVENT_POS_EDGE);
    TimerLoadSet(WTIMER5_BASE, TIMER_B, cuenta_interrupcion+1); // 1MHz OK
    TimerMatchSet(WTIMER5_BASE,TIMER_B, cuenta_interrupcion);
     
     
          // TimerIntEnable(WTIMER5_BASE, TIMER_CAPB_EVENT);//Every edge
        TimerIntEnable(WTIMER5_BASE, TIMER_CAPB_MATCH); //FUNCIONA!!
        TimerEnable(WTIMER5_BASE, TIMER_B);
     
        IntEnable(INT_WTIMER5B);
     
         
    }