电机学习笔记 输入捕获

一、输入捕获简介

输入捕获可以对输入的信号的上升沿,下降沿或者双边沿进行捕获,常用的有测量输入信号的脉
宽和测量 PWM 输入信号的频率和占空比这两种。

输入捕获的大概的原理就是,当捕获到信号的跳变沿的时候,把计数器 CNT 的值锁存到捕获寄
存器 CCR 中,把前后两次捕获到的 CCR 寄存器中的值相减,就可以算出脉宽或者频率。如果捕
获的脉宽的时间长度超过你的捕获定时器的周期,就会发生溢出,这个我们需要做额外的处理。

输入捕获一般应用在两个方面,一个方面是脉冲跳变沿时间测量,另一方面是 PWM 输入测量

测量脉宽或者频率

在这里插入图片描述

测量频率

当捕获通道 TIx 上出现上升沿时,发生第一次捕获,计数器 CNT 的值会被锁存到捕获寄存器
CCR 中,而且还会进入捕获中断,在中断服务程序中记录一次捕获(可以用一个标志变量来记
录),并把捕获寄存器中的值读取到 value1 中。当出现第二次上升沿时,发生第二次捕获,计数
器 CNT 的值会再次被锁存到捕获寄存器 CCR 中,并再次进入捕获中断,在捕获中断中,把捕
获寄存器的值读取到 value3 中,并清除捕获记录标志。利用 value3 和 value1 的差值我们就可以
算出信号的周期(频率)。

测量脉宽

当捕获通道 TIx 上出现上升沿时,发生第一次捕获,计数器 CNT 的值会被锁存到捕获寄存器
CCR 中,而且还会进入捕获中断,在中断服务程序中记录一次捕获(可以用一个标志变量来记
录),并把捕获寄存器中的值读取到 value1 中。然后把捕获边沿改变为下降沿捕获,目的是捕获
后面的下降沿。当下降沿到来的时候,发生第二次捕获,计数器 CNT 的值会再次被锁存到捕获
寄存器 CCR 中,并再次进入捕获中断,在捕获中断中,把捕获寄存器的值读取到 value2 中,并
清除捕获记录标志。然后把捕获边沿设置为上升沿捕获。
在测量脉宽过程中需要来回的切换捕获边沿的极性,如果测量的脉宽时间比较长,定时器就会发
生溢出,溢出的时候会产生更新中断,我们可以在中断里面对溢出进行记录处理

PWM 输入模式

测量脉宽和频率还有一个更简便的方法就是使用 PWM 输入模式。与上面那种只使用一个捕获
寄存器测量脉宽和频率的方法相比,PWM 输入模式需要占用两个捕获寄存器。

在这里插入图片描述输入通道和捕获通道的关系映射图
当使用 PWM 输入模式的时候,因为一个输入通道 (TIx) 会占用两个捕获通道 (ICx),所以一个
定时器在使用 PWM 输入的时候最多只能使用两个输入通道 (TIx)。
我们以输入通道 TI1 工作在 PWM 输入模式为例来讲解下具体的工作原理,其他通道以此类推即可。

PWM 信号由输入通道 TI1 进入,因为是 PWM 输入模式的缘故,信号会被分为两路,一路是
TI1FP1,另外一路是 TI1FP2。其中一路是周期,另一路是占空比,具体哪一路信号对应周期还
是占空比,得从程序上设置哪一路信号作为触发输入,作为触发输入的哪一路信号对应的就是
周期,另一路就是对应占空比。作为触发输入的那一路信号还需要设置极性,是上升沿还是下降
沿捕获,一旦设置好触发输入的极性,另外一路硬件就会自动配置为相反的极性捕获,无需软件
配置。一句话概括就是:选定输入通道,确定触发信号,然后设置触发信号的极性即可,因为是
PWM 输入的缘故,另一路信号则由硬件配置,无需软件配置。
当使用 PWM 输入模式的时候必须将从模式控制器配置为复位模式(配置寄存器 SMCR 的位
SMS[2:0] 来实现),即当我们启动触发信号开始进行捕获的时候,同时把计数器 CNT 复位清零
下面我们以一个更加具体的时序图来分析下 PWM 输入模式。

在这里插入图片描述
PWM 输入模式时序
PWM 信号由输入通道 TI1 进入,配置 TI1FP1 为触发信号,上升沿捕获。当上升沿的时候 IC1
和 IC2 同时捕获,计数器 CNT 清零,到了下降沿的时候,IC2 捕获,此时计数器 CNT 的值被
锁存到捕获寄存器 CCR2 中,到了下一个上升沿的时候,IC1 捕获,计数器 CNT 的值被锁存到
捕获寄存器 CCR1 中。其中 CCR2 测量的是脉宽,CCR1 测量的是周期。

配置

在这里插入图片描述这里从模式选择Reset Mode
触发源 选择 TI1FP1
channel1 选择 input Capture direct mode
channel1 选择 input Capture indirect mode

IC1 的信号可以是 TI1 输入的 TI1FP1,我们设置为上升沿
也可以是从 TI2 输入的 TI2FP1,我们这里选择直连(DIRECTTI),即 IC1 映射到 TI1FP1,即
PWM 信号从 TI1 输入。

PWM 输入模式,需要使用两个捕获通道,占用两个捕获寄存器。由输入通道 TI1 输
入的信号会分成 TI1FP1 和 TI1FP2,具体选择哪一路信号作为捕获触发信号决定着哪个捕获通
道测量的是周期。这里我们选择 TI1FP1 作为捕获的触发信号,那 PWM 信号的周期则存储在
CCR1 寄存器中,剩下的另外一路信号 TI1FP2 则进入 IC2,CCR2 寄存器存储的是脉冲宽度。

测量脉冲宽度我们选择捕获通道 2,即 IC2,设置捕获信号的极性,这里我们配置为下降沿,我们
需要对捕获信号的每个有效边沿(即我们设置的下降沿)都捕获,所以我们不分频,滤波器我们
也不需要用。那么捕获通道的信号来源于 TI2 输入的 TI2FP1,这里选择间接(INDIRECTTI),
PWM 信号从 IC1 输入再进入 IC2.
IC2 作为间接输入模式,我们需要配置他的从模式,即从模式复位模式,定时器触发源为
TIM_TS_TI1FP1,最后使用函数 HAL_TIM_SlaveConfigSynchronization 进行配置。
在这里插入图片描述

代码生成后

/* TIM8 init function */
void MX_TIM8_Init(void)
{
  TIM_SlaveConfigTypeDef sSlaveConfig = {0};
  TIM_MasterConfigTypeDef sMasterConfig = {0};
  TIM_IC_InitTypeDef sConfigIC = {0};

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

    HAL_TIM_IC_Start_IT(&htim8,TIM_CHANNEL_1);
	HAL_TIM_IC_Start_IT(&htim8,TIM_CHANNEL_2);
}

不要忘了启用

    HAL_TIM_IC_Start_IT(&htim8,TIM_CHANNEL_1);
	HAL_TIM_IC_Start_IT(&htim8,TIM_CHANNEL_2);

后在重写HAL_TIM_IC_CaptureCallback 在中断中获取捕获值

中断服务函数的回调函数中,我们获取 CCR1 和 CCR2 寄存器中的值,当 CCR1 的值不为 0 时,
说明有效捕获到了一个周期,然后计算出频率和占空比。
如果是第一个上升沿中断,计数器会被复位,锁存到 CCR1 寄存器的值是 0,CCR2 寄存器的值
也是 0,无法计算频率和占空比。当第二次上升沿到来的时候,CCR1 和 CCR2 捕获到的才是有
效的值

void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
			if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1)
				{
					/* 获取输入捕获值 */
					IC1Value = HAL_TIM_ReadCapturedValue(&htim8,TIM_CHANNEL_1);
					IC2Value = HAL_TIM_ReadCapturedValue(&htim8,TIM_CHANNEL_2);
				if(IC1Value !=0)
				{
					//占空比计算
					DutyCycle = (float)((IC2Value+1) * 100) / (IC1Value+1);
					 /* 频率计算 */
          			Frequency = 168000000/168/(float)(IC1Value+1);
				}
				else
				{
					DutyCycle = 0;
					Frequency = 0;
				}
			}
}

我们这里看占空比计算
DutyCycle = (float)((IC2Value+1) * 100) / (IC1Value+1);
前面的知识知道
IC1Value是 pwm信号的周期(Period)
IC2Value是 脉冲宽度(Pulse)

占空比为:(Pulse+1)/(Period+1)

*100 是为了好百分比显示

pwm频率=1000000/Period = 大概100hz

在这里插入图片描述

  • 7
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值