好记性不如铅笔头

ARM, STM32, 操作系统

STM32CubeMX简单使用笔记:使用硬件定时器PWM输入检测PWM

因为项目需要,最近重新拾起来STM32,正好趁着这个机会好好的梳理下遇到的知识细节。

参考链接
https://blog.csdn.net/qq86376032/article/details/80496853
【 https://cstriker1407.info/blog/stm32-timer-ti1fp1-ti2fp2/

STM32的硬件定时器有个 PWM输入 模式,可以快速的检测PWM频率和占空比,不过缺点是需要占用定时器的两个通道,这里简单的笔记下如何通过STM32CubeMX来使用该功能。
假如我们要使用TIM2的channel1作为PWM输入端口,在使用PWM输入模式下,channel2作为channel1的配对端口,也会被占用

最方便配置如下图,直接设置Combined Channels选项,如下图:

此时可以发现channel1,channel2都不可编辑,而且各类配置已经配置好了。
然后我们使能中断响应处理,如下图:

我们保存配置,IDE会自动生成代码,此时就可以看到IDE自动生成了如下定时器初始化代码:

static void MX_TIM2_Init(void)
{
  TIM_SlaveConfigTypeDef sSlaveConfig = {0};
  TIM_IC_InitTypeDef sConfigIC = {0};
  TIM_MasterConfigTypeDef sMasterConfig = {0};

  htim2.Instance = TIM2;
  htim2.Init.Prescaler = 83;
  htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim2.Init.Period = 4294967295;
  htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
  if (HAL_TIM_IC_Init(&htim2) != HAL_OK)
  {
    Error_Handler();
  }
  sSlaveConfig.SlaveMode = TIM_SLAVEMODE_RESET;
  sSlaveConfig.InputTrigger = TIM_TS_TI1FP1;
  sSlaveConfig.TriggerPolarity = TIM_INPUTCHANNELPOLARITY_RISING;
  sSlaveConfig.TriggerPrescaler = TIM_ICPSC_DIV1;
  sSlaveConfig.TriggerFilter = 0;
  if (HAL_TIM_SlaveConfigSynchro(&htim2, &sSlaveConfig) != HAL_OK)
  {
    Error_Handler();
  }
  sConfigIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_RISING;
  sConfigIC.ICSelection = TIM_ICSELECTION_DIRECTTI;
  sConfigIC.ICPrescaler = TIM_ICPSC_DIV1;
  sConfigIC.ICFilter = 0;
  if (HAL_TIM_IC_ConfigChannel(&htim2, &sConfigIC, TIM_CHANNEL_1) != HAL_OK)
  {
    Error_Handler();
  }
  sConfigIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_FALLING;
  sConfigIC.ICSelection = TIM_ICSELECTION_INDIRECTTI;
  if (HAL_TIM_IC_ConfigChannel(&htim2, &sConfigIC, TIM_CHANNEL_2) != HAL_OK)
  {
    Error_Handler();
  }
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK)
  {
    Error_Handler();
  }
}

和一个默认的中断响应函数:

void TIM2_IRQHandler(void)
{
  /* USER CODE BEGIN TIM2_IRQn 0 */

  /* USER CODE END TIM2_IRQn 0 */
  HAL_TIM_IRQHandler(&htim2);
  /* USER CODE BEGIN TIM2_IRQn 1 */

  /* USER CODE END TIM2_IRQn 1 */
}

此时我们增加自己的中断业务响应函数:

void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
	if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1)
	{
		chan1_cap_data = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_1);
	}
	else if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_2)
	{
		chan2_cap_data = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_2);
	}
	else
	{
        。。。
	}
。。。
}

那么PWM信息就可以计算为:

/*
tim_ticket_pre_second为定时器频率,计算公式为:
HAL_RCC_GetPCLK1Freq() * 2 / (htim2.Init.Prescaler + 1) 
*/
		duty_circle = 100 * chan2_cap_data / chan1_cap_data;
		frequency = tim_ticket_pre_second / chan1_cap_data;

 

Leave a Reply

2 + 9 =

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据