单片机定时器/计数器实战教程

时光旅行者酱 2023-04-02 ⋅ 16 阅读

简介

单片机的定时器/计数器是一种非常常见的功能模块,可以用来精确测量时间间隔、生成定时中断、计数等。在本教程中,我们将重点介绍如何使用定时器/计数器来进行频率计算,即测量外部信号的频率。

原理

单片机的定时器/计数器一般可以计数外部信号的边缘上升或下降沿,根据计数器的溢出周期和计数值,我们可以计算出外部信号的频率。

假设我们要测量一个频率为F的方波信号,周期为T,那么该信号的高电平时间为T/2,低电平时间也为T/2。我们可以使用定时器/计数器计算出方波信号高电平时间的计数值Count_high,然后计算频率F:

F = 1 / (T/2) = 2 / T

因为定时器/计数器一般工作在单位时间计数一次的模式,所以我们可以将计数值Count_high除以定时器的溢出周期,得到一个比例因子,然后与常数2除以溢出周期的结果相乘,即可得到频率。

硬件准备

  • 单片机开发板
  • 外部方波源
  • Jumper线

软件实现

这里以STM32单片机为例,使用STM32CubeIDE开发环境。

首先,我们需要配置定时器/计数器的工作模式以及溢出周期。将定时器/计数器设置为边沿计数模式,计数器边沿为上升沿,同时设置溢出周期为定时器的最大计数值。

//代码片段 1: 定时器/计数器配置

TIM_HandleTypeDef htim2;

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

  htim2.Instance = TIM2;
  htim2.Init.Prescaler = 0;
  htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim2.Init.Period = 0xFFFFFFFF;
  if (HAL_TIM_IC_Init(&htim2) != HAL_OK)
  {
    Error_Handler();
  }

  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != 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();
  }
}

然后,我们需要编写中断处理函数,在计数器溢出时执行,并在方波信号出现上升沿时执行。在定时器中断函数中,我们可以获取到计数器的计数值,并根据方波信号的高电平时间计算出频率。

//代码片段 2: 定时器中断处理函数

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
  if (htim->Instance == TIM2)
  {
    // 定时器溢出时执行的代码
    uint32_t countValue = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_1);
    float frequency = (float)countValue * 2.0 / 0xFFFFFFFF;
    // 在此处处理频率数据
  }
}

void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
  if (htim->Instance == TIM2)
  {
    // 上升沿中断执行的代码
    // 在此处记录方波信号的上升沿时间
  }
}

最后,在main函数中配置定时器/计数器,并使能中断。

//代码片段 3: 主函数

int main(void)
{
  HAL_Init();
  SystemClock_Config();
  MX_TIM2_Init();

  HAL_TIM_Base_Start_IT(&htim2);
  HAL_TIM_IC_Start_IT(&htim2, TIM_CHANNEL_1);

  while (1)
  {
    // 在此处执行其他代码
  }
}

结论

通过以上步骤,我们成功配置了定时器/计数器,并使用中断来测量外部方波信号的频率。我们可以在定时器中断函数中,获取方波信号的高电平时间计数值,并根据公式计算出频率。这个频率可以用于许多应用,例如测量传感器输出的频率、控制器的PWM调光等。

希望这篇教程能够帮助到大家,如有疑问或建议,请留言讨论。谢谢!

参考资料:


全部评论: 0

    我有话说: