Skip to main content
Senior
May 4, 2025
Question

How to setup TIM16 and TIM17 for IR transmitter on PB9

  • May 4, 2025
  • 5 replies
  • 599 views

I can not get any output on PB9 after setting TIM16_Init:

void MX_TIM16_Init(void)
{

 /* USER CODE BEGIN TIM16_Init 0 */

 /* USER CODE END TIM16_Init 0 */

 TIM_OC_InitTypeDef sConfigOC = {0};
 TIM_BreakDeadTimeConfigTypeDef sBreakDeadTimeConfig = {0};

 /* USER CODE BEGIN TIM16_Init 1 */

 /* USER CODE END TIM16_Init 1 */
 htim16.Instance = TIM16;
 htim16.Init.Prescaler = 32000;
 htim16.Init.CounterMode = TIM_COUNTERMODE_UP;
 htim16.Init.Period = 65535;
 htim16.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
 htim16.Init.RepetitionCounter = 0;
 htim16.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE; // TIM_AUTORELOAD_PRELOAD_DISABLE;
 if (HAL_TIM_Base_Init(&htim16) != HAL_OK)
 {
 Error_Handler();
 }
 if (HAL_TIM_OC_Init(&htim16) != HAL_OK)
 {
 Error_Handler();
 }
 sConfigOC.OCMode = TIM_OCMODE_TIMING;
 sConfigOC.Pulse = 0;
 sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
 sConfigOC.OCNPolarity = TIM_OCNPOLARITY_HIGH;
 sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
 sConfigOC.OCIdleState = TIM_OCIDLESTATE_RESET;
 sConfigOC.OCNIdleState = TIM_OCNIDLESTATE_RESET;
 if (HAL_TIM_OC_ConfigChannel(&htim16, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)
 {
 Error_Handler();
 }
 sBreakDeadTimeConfig.OffStateRunMode = TIM_OSSR_DISABLE;
 sBreakDeadTimeConfig.OffStateIDLEMode = TIM_OSSI_DISABLE;
 sBreakDeadTimeConfig.LockLevel = TIM_LOCKLEVEL_OFF;
 sBreakDeadTimeConfig.DeadTime = 0;
 sBreakDeadTimeConfig.BreakState = TIM_BREAK_DISABLE;
 sBreakDeadTimeConfig.BreakPolarity = TIM_BREAKPOLARITY_HIGH;
 sBreakDeadTimeConfig.BreakFilter = 0;
 sBreakDeadTimeConfig.AutomaticOutput = TIM_AUTOMATICOUTPUT_DISABLE;
 if (HAL_TIMEx_ConfigBreakDeadTime(&htim16, &sBreakDeadTimeConfig) != HAL_OK)
 {
 Error_Handler();
 }
 /* USER CODE BEGIN TIM16_Init 2 */

 /* USER CODE END TIM16_Init 2 */
 HAL_TIM_Base_MspInit(&htim16);
}

 and TIM17_Init;

void MX_TIM17_Init(void)
{

 /* USER CODE BEGIN TIM17_Init 0 */

 /* USER CODE END TIM17_Init 0 */

 TIM_OC_InitTypeDef sConfigOC = {0};
 TIM_BreakDeadTimeConfigTypeDef sBreakDeadTimeConfig = {0};

 /* USER CODE BEGIN TIM17_Init 1 */

 /* USER CODE END TIM17_Init 1 */
 htim17.Instance = TIM17;
 htim17.Init.Prescaler = 0; //38 khz
 htim17.Init.CounterMode = TIM_COUNTERMODE_UP;
 htim17.Init.Period = 1725; //65535; // 1khz at 64Mhz	1msec // 63 - 1us// 1725 -38khz
 htim17.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
 htim17.Init.RepetitionCounter = 0;
 htim17.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
 if (HAL_TIM_Base_Init(&htim17) != HAL_OK)
 {
 Error_Handler();
 }
 if (HAL_TIM_OC_Init(&htim17) != HAL_OK)
 {
 Error_Handler();
 }
 sConfigOC.OCMode = TIM_OCMODE_TIMING;
 sConfigOC.Pulse = 0;
 sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
 sConfigOC.OCNPolarity = TIM_OCNPOLARITY_HIGH;
 sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
 sConfigOC.OCIdleState = TIM_OCIDLESTATE_RESET;
 sConfigOC.OCNIdleState = TIM_OCNIDLESTATE_RESET;
 if (HAL_TIM_OC_ConfigChannel(&htim17, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)
 {
 Error_Handler();
 }
 sBreakDeadTimeConfig.OffStateRunMode = TIM_OSSR_DISABLE;
 sBreakDeadTimeConfig.OffStateIDLEMode = TIM_OSSI_DISABLE;
 sBreakDeadTimeConfig.LockLevel = TIM_LOCKLEVEL_OFF;
 sBreakDeadTimeConfig.DeadTime = 0;
 sBreakDeadTimeConfig.BreakState = TIM_BREAK_DISABLE;
 sBreakDeadTimeConfig.BreakPolarity = TIM_BREAKPOLARITY_HIGH;
 sBreakDeadTimeConfig.BreakFilter = 0;
 sBreakDeadTimeConfig.AutomaticOutput = TIM_AUTOMATICOUTPUT_DISABLE;
 if (HAL_TIMEx_ConfigBreakDeadTime(&htim17, &sBreakDeadTimeConfig) != HAL_OK)
 {
 Error_Handler();
 }
 /* USER CODE BEGIN TIM17_Init 2 */

 /* USER CODE END TIM17_Init 2 */
 HAL_TIM_Base_MspInit(&htim17);
}

and MX_GPIO_Init:

	 GPIO_InitStruct.Pin = GPIO_PIN_9; // IR transmitter PB9
	 GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
	 GPIO_InitStruct.Pull = GPIO_NOPULL;
	 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
	 GPIO_InitStruct.Alternate = GPIO_AF8_IR;
	 HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

Using the follow code in main:

		__HAL_RCC_TIM16_CLK_ENABLE();
		__HAL_RCC_TIM17_CLK_ENABLE();

		 __HAL_TIM_ENABLE(&htim17);
		 HAL_TIM_Base_Start(&htim17);
		HAL_TIM_PWM_Start(&htim17, TIM_CHANNEL_1);

		__HAL_TIM_SET_COMPARE(&htim16, TIM_CHANNEL_1, 1000); // duty cycle

		 __HAL_TIM_ENABLE(&htim16);
		 HAL_TIM_Base_Start(&htim16);
		HAL_TIM_PWM_Start(&htim16, TIM_CHANNEL_1);

What else should I try? Thanks.

5 replies

waclawek.jan
Super User
May 4, 2025
 htim16.Init.Prescaler = 32000;
 htim16.Init.CounterMode = TIM_COUNTERMODE_UP;
 htim16.Init.Period = 65535;

this sets the modulation "frequency" to the range of 0.01Hz (i.e. period around a minute). Is this what you intend?

JW

 

GS2Author
Senior
May 4, 2025

Yes, I would like to see any changes on PB9 using voltmeter.

waclawek.jan
Super User
May 5, 2025

And did you wait *minutes* to observe the change?

JW

GS2Author
Senior
May 6, 2025

Thanks, I have try many options - including  - htim16.Init.Prescaler = 1000; - 1 sec.

Same voltage - 2.378 V from __HAL_RCC_TIM16_CLK_ENABLE();
to HAL_TIM_PWM_Start(&htim16, TIM_CHANNEL_1);

waclawek.jan
Super User
May 6, 2025

I don't know then, sorry.

JW

STTwo-32
Technical Moderator
May 22, 2025

Hello @GS2 

I suggest you review the implementation on the X-Cube-IRREMOTE and try to adapt the examples to the STM32WB. It should be easy to migrate specially with the help of the AN4834.

Best Regards.

STTwo-32