cancel
Showing results for 
Search instead for 
Did you mean: 

TIM2 timer ETR accuracy question on STM32F303RE Nucleo board

David Pekin
Senior

Hello,

I've taken the code from the Timer cookbook example TIM_ExtCLK_ETR and modified it slightly for my purposes. I removed the DMA transfer and am looking directly at the TIM2->CNT variable at a 1 second interval for right now. In this case, I'm simply reading the ETR timer clock count only, not the channel 2 input which is tied to ground. A signal generator is routed to the ETR pin PA0 for this test.

For testing purposes every second I do this:

      

     now = *DWT_CYCCNT;  // system clock tic - rolls over about 1 per minute

     cnt = TIM2->CNT; // Should be ETR clock tics

     printf(" (%d, %d)", cnt - lastcnt, now-lastnow);

    lastcnt = cnt;

    lastnow = now;

So, you see I'm printing out the number of ETR clock cycles and the system clock ticks that occurred during the last second.

The problem is that I'm getting on the order of 10-15% more ETR clock cycles than I should.

The clock count is pretty dead on so we are actually doing this accurately once per second.

With a 1Khz ETR signal (measured with o-scope) I'm getting (1125, 72000190) where in a perfect world I should get (1000, 72000000)

At 10KHz I get (10966, 72000145) and at At 100KHz I get (113000, 72000192)

Can anyone explain why the timer seems to count about 15% faster than the ETR clock pulses. And this is very repeatable so it's not noise.

Below is the setup of the TIM2.

Thanks!

/**

 * @brief Configure the TIM2 peripheral:

 * + ETR MODE : - HSI : 8MHz 

 *       - Divider : 1

 *       - Polarity : High

 *       - ETR pin : Channel 1

 * + Internal source clock mode: - HSI : 8MHz

 *

 *  Counter mode : UP Counter 

 *  Clock Division : 1

 *  Period : 0xFFFFFFFF

 *  Prescaler : 0 

 *  input Channel : Channel 2

 * @param None

 * @retval None

 */

static void TIM2_Config(void)

{

 /* TIM2 clock enable */

 RCC->APB1ENR |= RCC_APB1ENR_TIM2EN; 

 /* Set the Timer prescaler to 0 so we get all ETR tics */

 Prescaler = 0;

 /* Reset the SMCR register */

 TIM2->SMCR = RESET; 

  

 /* Configure the ETR Clock source:

    + Asychronous divider : 1

    + Polarity : Rising Edge

 */

 TIM2->SMCR |= (TIM_ETRPRESCALER_DIV1 | TIM_ETRPOLARITY_NONINVERTED);          

 TIM2->SMCR |= TIM_SMCR_ECE;            

 /* Configure the Time base:

    + Counter mode : UP Counter

    + Clock Division : 1

    + Period : 0xFFFFFFFF

    + Prescaler : 0

 */

 /* Select the up counter mode */

 TIM2->CR1 &= ~(TIM_CR1_DIR | TIM_CR1_CMS);

 TIM2->CR1 |= TIM_COUNTERMODE_UP;      

 /* Set the clock division to 1 */

 TIM2->CR1 &= ~TIM_CR1_CKD;

 TIM2->CR1 |= TIM_CLOCKDIVISION_DIV1;    

 /* Set the Autoreload value */

 TIM2->ARR = 0xFFFFFFFF;

 /* Set the Prescaler value */

 TIM2->PSC = Prescaler;    

 /* Generate an update event to reload the Prescaler value immediatly */

 TIM2->EGR = TIM_EGR_UG;

 /* Configure the Timer Input Capture Channels:

    + Channel : Channel 2

 */

 /* Connect the Timer input to IC2 */

 TIM2->CCMR1 &= ~TIM_CCMR1_CC2S;

 TIM2->CCMR1 |= TIM_CCMR1_CC2S_0;

}

The timer is started in Main by the following code.

 /*Enables the TIM Capture Compare Channel 2.*/

 TIM2->CCER |= TIM_CCER_CC2E;

 /*Enable the TIM2*/

 TIM2->CR1 |= TIM_CR1_CEN;

2 REPLIES 2

What is the primary timing source of the 1s?

JW

David Pekin
Senior

I need to track that down but I think you hit the nail on the head! The count is over by almost exactly the ratio of 72/64 so I'm pretty sure the answer will be in the clocks.

Thanks!