2
\$\begingroup\$

I'm trying to create a microsecond delay function using the STMs regular timer. I wanted to set a timer to fire an interrupt every microsecond and then increment a variable in the call back function which gets called at the end of the interrupt and if that variable has reached the desired value stop the counter with HAL_TIM_BASE_STOP_IT().

Normally when using the HAL library for STM32 at the end of an the interrupt, the interrupt handler calls a callback function. The callback functions are already declared but are left blank. The driver makes use of a nonstandard keyword weak which allows you to overload the callback function, by simply writing your own definition. I've successfully done this with the callback functions for the interrupts for I2C, UART, and SPI communication, but for the timer I get the following 3 errors.

Error[Pe079]: expected a type specifier C:\projects\automated_testing\voltage measurement node\Src\main.c 610 

Error[Pe147]: declaration is incompatible with "__interwork __softfp void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *)" (declared at line 1558 of "C:\projects\automated_testing\voltage measurement node\Drivers\ C:\projects\automated_testing\voltage measurement node\Src\main.c 610 

Error[Pe141]: unnamed prototyped parameters not allowed when body is present C:\projects\automated_testing\voltage measurement node\Src\main.c 610 

My function at the moment is literally just toggling a pin to see if it works. If I comment it out, it compiles fine.

void HAL_TIM_PeriodElapsedCallback(&htim3)
{
  HAL_GPIO_TogglePin(N_CS_GPIO_Port, N_CS_Pin);
}

Here's the configuration code for my timer created by STMCube to be in "Output Compare No Output" mode. I'm using HAL_TIM_Base_Start_IT(&htim3) to start the timer and does call the interrupt routine and get to the correct blank callback function when I don't create my own definition of the function.

* TIM3 init function */
static void MX_TIM3_Init(void)
{

  TIM_ClockConfigTypeDef sClockSourceConfig;
  TIM_MasterConfigTypeDef sMasterConfig;
  TIM_OC_InitTypeDef sConfigOC;

  htim3.Instance = TIM3;
  htim3.Init.Prescaler = 0;
  htim3.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim3.Init.Period = 72;
  htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
  if (HAL_TIM_Base_Init(&htim3) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

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

  if (HAL_TIM_OC_Init(&htim3) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

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

  sConfigOC.OCMode = TIM_OCMODE_TIMING;
  sConfigOC.Pulse = 0;
  sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
  sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
  if (HAL_TIM_OC_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

}

Any ideas as to what I've done wrong would be very helpful.

\$\endgroup\$
4
  • \$\begingroup\$ The 'weak' attribute is not nonstandard and is commonly used in just the way you describe...to let users override default handlers. \$\endgroup\$ Aug 3, 2018 at 14:48
  • 1
    \$\begingroup\$ What is at line 610 in your main.c? That seems like critical information. \$\endgroup\$ Aug 3, 2018 at 14:49
  • \$\begingroup\$ I used the term non standard as when I first came across it and looked into it I found that it wasn't defined in the C language standards. "Weak symbols are not mentioned by the C or C++ language standards; as such, inserting them into code is not very portable." en.wikipedia.org/wiki/Weak_symbol \$\endgroup\$ Aug 3, 2018 at 14:55
  • 1
    \$\begingroup\$ Fair enough, I should have said that 'weak' is a common attribute provided by compilers. You are correct that it is not part of the language standard. \$\endgroup\$ Aug 3, 2018 at 15:28

1 Answer 1

3
\$\begingroup\$

You should add the type of htim in the function declaration which is missing in:

void HAL_TIM_PeriodElapsedCallback(&htim3)
{
  HAL_GPIO_TogglePin(N_CS_GPIO_Port, N_CS_Pin);
}

By adding it you will get:

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
  HAL_GPIO_TogglePin(N_CS_GPIO_Port, N_CS_Pin);
}

To check if the function is called for timer 3, check for the correct timer:

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
   if (htim == &htim3)
   {
      HAL_GPIO_TogglePin(N_CS_GPIO_Port, N_CS_Pin);
   }
}

(I do not have a compiler at hand, so I cannot check the code).

\$\endgroup\$
2
  • \$\begingroup\$ It works! You're a genius! Haha. Pretty silly mistake on my part, thank you very much. \$\endgroup\$ Aug 3, 2018 at 14:52
  • \$\begingroup\$ No problem and good luck with your project. \$\endgroup\$ Aug 3, 2018 at 14:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.