3

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.

John Gaby
  • 1,500
  • 3
  • 19
  • 33
  • Posting the code provides more clarity than describing the code. – chux - Reinstate Monica May 11 '18 at 02:08
  • Do you enable the clock for `tim2` anywhere? If you're using HAL it will be a call `RCCAPB1ClkCmd` – Colin May 11 '18 at 07:10
  • if you have the debugger just try to change value of the any TIM2 registers. If it changes - clock is enabled. – 0___________ May 11 '18 at 08:04
  • 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 May 11 '18 at 14:04
  • 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 May 11 '18 at 14:26
  • I am using HAL and that function does not exist. I searched for all instances of APB1 to see if there was some equivalent, but did not find anything relevant. I am using STM32CubeMX to generate the initialization code for the timer and I am not sure why it is not generating all the code needed for the timer to function properly. Perhaps, I have not setup the parameters correctly? – John Gaby May 11 '18 at 15:17
  • @Colin__s `RCC_APB1PeriphClockCmd()` is in StdPeriph, not in HAL. – followed Monica to Codidact May 11 '18 at 18:13
  • Ah, thanks @berendi. – Colin May 11 '18 at 19:00
  • I'm typing on a phone so I can't do a proper answer right now but you might take a look at what I've done in this answer here to configure the timer. I set it up from scratch, without CubeMx, but using HAL. https://stackoverflow.com/a/50032992/4561887. My timer code is at the very bottom of that answer. – Gabriel Staples May 12 '18 at 06:41

4 Answers4

7

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;
}
  • There was do definition for TIM_CR1_EN, but I did find TIM_CR1_CEN whose comment indicates that it is the timer enable. I tried that but still always get zero for the count. Also looking through the HAL code, the two lines that I already had seem to be doing the same as the code above. There must be something fundamental that I am missing here. – John Gaby May 11 '18 at 19:24
  • Actually, I was finally able to get this to work by commenting out the timer initialization code that was generated by STM32CubeMX, so it appears that whatever it was doing was incorrect. – John Gaby May 11 '18 at 20:04
2

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

Lamaatje
  • 21
  • 3
1

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

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.

Vega
  • 27,856
  • 27
  • 95
  • 103