cancel
Showing results for 
Search instead for 
Did you mean: 

Basic timer 6 for time counting using interrupt

NSemrHomeInit
Senior

Dear ST Hello

I am using timer 6 to calculate the time for timer interrupt triggering,

I am using the example for the board from the cube BSP folder,

\STM32Cube\Repository\STM32Cube_FW_F4_V1.27.1\Projects\STM32F429I-Discovery\Examples\BSP\SW4STM32\STM32F429I-Discovery

In this project, I disable some functions and want to add an interrupt using timer 6.

I generated the code using another project for the interrupt and timer configuration and I integrated the hal timer and timer ex to build the project, I also defined the HAL_TIM_MODULE_ENABLED.

here is the code:

  /* Configure USER Button */
  //BSP_PB_Init(BUTTON_KEY, BUTTON_MODE_EXTI);
  MX_TIM6_Init();
  
  /*##-1- Initialize the LCD #################################################*/
  /* Initialize the LCD */
  //BSP_LCD_Init();
  
  /* Initialize the LCD Layers */
  //BSP_LCD_LayerDefaultInit(1, LCD_FRAME_BUFFER);
  
  //Display_DemoDescription();
  HAL_TIM_Base_Start_IT(&htim6);
 
 
 
static void MX_TIM6_Init(void)
{
 
  /* USER CODE BEGIN TIM6_Init 0 */
 
  /* USER CODE END TIM6_Init 0 */
 
  TIM_MasterConfigTypeDef sMasterConfig = {0};
 
  /* USER CODE BEGIN TIM6_Init 1 */
 
  /* USER CODE END TIM6_Init 1 */
  htim6.Instance = TIM6;
  htim6.Init.Prescaler = 90-1;
  htim6.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim6.Init.Period = 10000-1;
  htim6.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
  if (HAL_TIM_Base_Init(&htim6) != HAL_OK)
  {
    Error_Handler();
  }
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_UPDATE;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  if (HAL_TIMEx_MasterConfigSynchronization(&htim6, &sMasterConfig) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN TIM6_Init 2 */
 
  /* USER CODE END TIM6_Init 2 */
 
}
 
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
	if(htim == &htim6)
	{
		//toggel an led
		BSP_LED_Toggle(LED3);
		BSP_LED_Toggle(LED4);
	}
}
 
 
 
 
void TIM6_DAC_IRQHandler(void)
{
  /* USER CODE BEGIN TIM6_DAC_IRQn 0 */
 
  /* USER CODE END TIM6_DAC_IRQn 0 */
  HAL_TIM_IRQHandler(&htim6);
  /* USER CODE BEGIN TIM6_DAC_IRQn 1 */
 
  /* USER CODE END TIM6_DAC_IRQn 1 */
}

When I was in the timer init function, I couldn't see the configuration I set for timer 6 in the expression watch, it look all zeros.

In the init function there is a function called HAL_TIM_Base_MspInit(htim);

I am not sure that this function is being called correctly because there is a _weak function and the compilation is done without any error.

Do I have to enable anything cause I am not using the CubeMx?

Thank you in advance,

:)

1 ACCEPTED SOLUTION

Accepted Solutions

No, that's the handler, associated via the Vector Table, that's calling in to the HAL so it can then dispatch the call-backs.

The interrupt is enabled in the *peripheral* via HAL_TIM_Base_Start_IT()

You still need to enable it in the NVIC

Perhaps in the MSP code? One function needs to service all TIM's initialized

void HAL_TIM_Base_MspInit(TIM_HandleTypeDef *htim)

{

if (htim->Instance ==TIM6) // Init code for TIM6

{

 /*##-1- Enable peripheral clock #################################*/

 /* TIMx Peripheral clock enable */

 TIM6_CLK_ENABLE();

 /*##-2- Configure the NVIC for TIMx ########################################*/

 /* Set the TIMx priority */

 HAL_NVIC_SetPriority(TIM6_DAC_IRQn, 3, 0);

 /* Enable the TIMx global Interrupt */

 HAL_NVIC_EnableIRQ(TIM6_DAC_IRQn);

}

}

If you're not enabling it would explain why it's not occurring.

Instrument the code so you understand if the functions are being called.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

View solution in original post

8 REPLIES 8
KnarfB
Principal III

You are expected to provide a specific implementation of HAL_TIM_Base_MspInit that suits your purposes. See in the parallel example TIM\TIM_TimeBase\Src\stm32f4xx_hal_msp.c

Even if you don't like/want to use CubeMx in your final code, use it to learn from CubeMx generated code :)

hth

KnarfB

NSemrHomeInit
Senior

No, I am not expecting to change anything in the hal lib, The only thing is that my code is not running and the interrupt is not coming. yes, I use cube but sometimes I don't have time to instantiate all the projects in cube. I use it as it is.

You enable the NVIC where?

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

I use to use cube and I think is done like this:

/**
  * @brief This function handles TIM6 global interrupt, DAC1 and DAC2 underrun error interrupts.
  */
void TIM6_DAC_IRQHandler(void)
{
  /* USER CODE BEGIN TIM6_DAC_IRQn 0 */
 
  /* USER CODE END TIM6_DAC_IRQn 0 */
  HAL_TIM_IRQHandler(&htim6);
  /* USER CODE BEGIN TIM6_DAC_IRQn 1 */
 
  /* USER CODE END TIM6_DAC_IRQn 1 */
}

> it look all zeros.

What, the timer registers?

Did you enable timer clock in RCC?

JW

I think, yes:

static void SystemClock_Config(void) {
	RCC_ClkInitTypeDef RCC_ClkInitStruct;
	RCC_OscInitTypeDef RCC_OscInitStruct;
 
	/* Enable Power Control clock */
	__HAL_RCC_PWR_CLK_ENABLE();
 
	/* The voltage scaling allows optimizing the power consumption when the device is
	 clocked below the maximum system frequency, to update the voltage scaling value
	 regarding system frequency refer to product datasheet.  */
	__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
 
	/* Enable HSE Oscillator and activate PLL with HSE as source */
	RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
	RCC_OscInitStruct.HSEState = RCC_HSE_ON;
	RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
	RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
	RCC_OscInitStruct.PLL.PLLM = 8;
	RCC_OscInitStruct.PLL.PLLN = 360;
	RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
	RCC_OscInitStruct.PLL.PLLQ = 7;
	HAL_RCC_OscConfig(&RCC_OscInitStruct);
 
	/* Activate the Over-Drive mode */
	HAL_PWREx_EnableOverDrive();
 
	/* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2
	 clocks dividers */
	RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK
			| RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
	RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
	RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
	RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
	RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
	HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5);
}

No, that's the handler, associated via the Vector Table, that's calling in to the HAL so it can then dispatch the call-backs.

The interrupt is enabled in the *peripheral* via HAL_TIM_Base_Start_IT()

You still need to enable it in the NVIC

Perhaps in the MSP code? One function needs to service all TIM's initialized

void HAL_TIM_Base_MspInit(TIM_HandleTypeDef *htim)

{

if (htim->Instance ==TIM6) // Init code for TIM6

{

 /*##-1- Enable peripheral clock #################################*/

 /* TIMx Peripheral clock enable */

 TIM6_CLK_ENABLE();

 /*##-2- Configure the NVIC for TIMx ########################################*/

 /* Set the TIMx priority */

 HAL_NVIC_SetPriority(TIM6_DAC_IRQn, 3, 0);

 /* Enable the TIMx global Interrupt */

 HAL_NVIC_EnableIRQ(TIM6_DAC_IRQn);

}

}

If you're not enabling it would explain why it's not occurring.

Instrument the code so you understand if the functions are being called.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

yes this was the problem the HAL_TIM_Base_MspInit was not declared.

cube declare this in a stm32f4xx_hal_msp.c file and in this file we overload the _weak function, it working now thank you!