1
votes

I am using a STM32F103 chip and I am trying to configure and use one of the timers. I have used STM32CubeMX to generation code which initializes Timer 2. I start the timer by calling HAL_TIM_Base_Start. Then, in a loop, I print out the current timer value via a call to htim2.Instance->CNT, or alternately by calling the macro __HAL_TIM_GetCounter (which I believe just returns the same value). However, no matter what I do, the count value shows up as zero. I have also tried calling __TIM2_CLK_ENABLE() at the beginning, but it makes no difference.

I have searched for a solution and have found a couple of questions about this issue, but have not found the solution.

Does anyone know what I am doing wrong?

Thanks.

Here is the routine that initializes the timer. This code was generated by STM32CubeMX and I have not modified it:

/* TIM2 init function */
static void MX_TIM2_Init(void)
{

  TIM_ClockConfigTypeDef sClockSourceConfig;
  TIM_MasterConfigTypeDef sMasterConfig;

  htim2.Instance = TIM2;
  htim2.Init.Prescaler = 0;
  htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim2.Init.Period = 0;
  htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
  if (HAL_TIM_Base_Init(&htim2) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

  sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
  if (HAL_TIM_ConfigClockSource(&htim2, &sClockSourceConfig) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

}

Then in the main I attempt to start the timer and attempt to print out it's value. This is the code that I use to do that:

__TIM2_CLK_ENABLE();;
HAL_TIM_Base_Start(&htim2);

while (true)
{
    Serial.println((long) __HAL_TIM_GetCounter(&htim2));
    delay(100);
}

The 'Serial' class is a class that I wrote which communicates with my PC via a USB serial port.

4
Posting the code provides more clarity than describing the code. - chux - Reinstate Monica
Do you enable the clock for tim2 anywhere? If you're using HAL it will be a call RCCAPB1ClkCmd - Colin
if you have the debugger just try to change value of the any TIM2 registers. If it changes - clock is enabled. - 0___________
I cannot find any function called RCCAPB1ClkCmd in the code, and a search of the internet for that returns no results. Can you give me more information on that? - John Gaby
Forgive me, I'm not familiar with the ST library (I don't use them, just stick to the datasheet), the function may be RCC_APB1PeriphClockCmd - Colin

4 Answers

4
votes

Try it without HAL, it's not complicated.

void start_TIM2() {
  RCC->APB1ENR |= RCC_APB1ENR_TIM2EN;
  TIM2->CR1 |= TIM_CR1_EN;
}

uint16_t read_TIM2() {
  return TIM2->CNT;
}
2
votes

Setting the value of

htim2.Init.Period = 0;

zero initializes the auto reload register (ARR) not a very handy default choice of cubeMX, you probably want an ARR value of 0xFFFFFFFF

The accepted answer relies on the ARR value after reset of 0xFFFFFFFF without mentioning it, more luck than wisdom if you ask me

1
votes

The ARR (htim2.Init.Period) shouldn't be 0. It will try to count uptil...0! Put some 16 bit integer there. Good Luck!

0
votes

I will show you some formulas to keep in mind: (refer: AN4776)

. Frequency = Fclk(timer) / (prescaler + 1)

For example, you chose prescaler = 0, it implies that your timer finishes counting [0: count) in a period of 1 / 80MHz, in case the SystemClock is configured like this (you should check the value of the clock and the prescaler to determine the Update frequency).

. #1_count(s) = 1 / Frequency

. period(s) = #1_count * (counter + 1) 

--> Let's see it with an example:

SystemClock = 72MHz, requires a 1us resolution timer and a 1ms period.

. for a 1us of resolution -> Frequency = 1Mhz

'1MHz = 72MHz / (prescaler + 1)' -> prescaler = 71 

. so that the timer interrupts every one millisecond we must calculate how much it should count:

'1ms = 1us * (counter + 1)' -> count = 999

with these values we configure the following:

htim2.Init.Prescaler = 71;

htim2.Init.Period = 999;

where the timer will count from 0: 999 in steps of 1uS.

Your code has two problems, the timer frequency is too high and it only counts from 0: 1, so you will never be able to see the increase in counts.