Skip to content

第五章 输入捕获

5.1 输入捕获

5.1.1 输入捕获介绍

  • IC(Input Capture)输入捕获
  • 输入捕获模式下,当通道输入引脚出现指定电平跳变时,当前CNT的值将被锁存到CCR中,可用于测量PWM波形的频率、占空比、脉冲间隔、电平持续时间等参数
  • 每个高级定时器和通用定时器都拥有4个输入捕获通道
  • 可配置为PWMI模式,同时测量频率和占空比
  • 可配合主从触发模式,实现硬件全自动测量

5.1.2 频率测量

频率测量分为测频法和测周法:

  • 测频法 ---> 一定闸门时间T内,记上升沿的次数 N ,取周期的倒数得可到频率: $$ f_x=\frac{N}{T} $$
  • 测周法 ---> 在两个上升沿之间,以 标准频率 计次N,即可得到频率: $$ f_x=\frac{f_c}{N} $$
  • 中界频率 ---让测周法和测频法中的 N 相等解出频率,得到测频法与测周法误差相等的频率点: $$ f_m=\sqrt\frac{f_c}{T} $$

1705737398459

Note

高频适合使用测频法,低频适合使用测周法,而中界频率即使选择方法的临界频率。

5.1.3 输入捕获框图

下面是输入捕获的框架:

  • 工作流程: 经过输入滤波器和极性选择进入预分频器,可以选择进行触发信号分频,然后触发信号进入捕获电路工作,每来一个触发信号,CNT的值向CCR转运一次,同时触发捕获事件,在状态寄存器置标志位触发中断,可以设置中断处理
  • 测周法实现: 以上升沿为触发信号,CNT计数器由内部标准时钟驱动(驱动时钟为\(\(f_c\)\) ),CNT数值即可记录两个上升沿的时间间隔,即为周期,取倒数可获得测周法的频率。

image-20241211210550007

Note

每次捕获以后要将CNT清零,可以用主从触发模式自动完成。

通道 1 和 2 互相交叉捕获可以在定时器总框图看的更清楚:

image-20241211210739260

5.2 主从触发模式

这个名字是从江协科技(以前叫江科大自化协)学来的。

5.2.1 主从触发模式简介

  • 主模式:将定时器内部的信号映射到TRGO引脚,用于触发别的外设。
  • 从模式:接收其他外设或自身外设的一些信号用于控制自身定时器的运行。(被其他信号控制)

1705746225685

5.2.2 主从模式选择

主模式各模式的信息,与表格中一一对应

image-20241211212745460

从模式触发源选择

image-20241211212955071

定时器的ITRx引脚对应

image-20241211213049917

从模式的模式选择,与表格中一一对应

image-20241211213146296

5.3 输入捕获基本结构

5.3.1 基础结构

输入信号源可以自定义引脚输出一固定频率的方波,引脚接到输入捕获的引脚

image-20241211221522415

执行逻辑如下:

  • 输入信号源经过滤波,确定极性,上升沿或下降沿触发输入捕获
  • 将CNT值写入CCR1寄存器
  • 同时TI1FP1经过触发源选择,触发从模式 Reset自动清零CNT

image-20241211221335809

5.3.2 PWMI模式

image-20241211222427955

Warning

注意这里TI1FP2并没有使用从模式,这是为了后面可以实现高电平单独测量,从而得出占空比的测量。

执行逻辑如下:

  • 输入信号源经过滤波,确定极性, 让上升沿触发输入捕获 1 ,下降沿触发输入捕获 2
  • 从第一个上升沿开始,经历第一个下降沿,将CNT值写入CCR2寄存器, 此时不会触发从模式清零CNT
  • 经历第二个上升沿,将CNT值写入CCR1寄存器, 并触发从模式清零CNT

image-20241211222600528

5.3.3 STM32CubeMX参数

各模式参数配置名称如下:

image-20241211234234617

从模式选择:

image-20241211234336301

  • Slave mode :从模式,也可以选择配置为 外部时钟 1
    • External Clock Mode 1:外部时钟模式 1
    • Reset Mode:复位模式
    • Gated Mode:门控模式
    • Trigger Mode:触发模式

与前面的表格对应,具体功能上面有介绍,在此不重复。外部时钟模式 1 在定时中断同样介绍过。

触发源选择:

image-20241211235052441

  • Trigger mode :从模式触发源选择。
    • ITR0
    • ITR1
    • ITR2
    • ITR3
    • ETR1(TIMx_ETR引脚)
    • T1_ED
    • T1FP1
    • TI2FP2

Warning

具体如何配置组合达到想要的功能,会在后面介绍,此处先熟悉各个参数与前面理论部分的对应。

输入捕获的通道模式:

image-20241205212240021

  • Input Capture Direct Mode ,在输入捕获直接模式下,定时器会直接捕获外部信号(例如TI1FP1)的脉冲并存储其时间戳。
  • Input Capture Indirect Mode ,在输入捕获间接模式下,输入捕获的触发源不是直接由外部信号决定,而是由另一个信号或事件(例如TI1FP2)触发。

Warning

以通道一为例,若是直接模式,即是走TI1FP1;而TI2FP1即是间接模式。若是通道二,则直接模式走TI2FP2;而间接模式走TI1FP2。结合定时框图会更容易理解,看 TF1 和 TF2 分别怎么走的。

  • **Input Capture Triggered by TRC ** ,该模式下,输入捕获功能会被外部触发信号(例如 TRC)所激活。

Warning

Input Capture Triggered by TRC 这个模式只有在触发源为ITRx时才可以选。

主模式参数选择:

image-20241211235509397

Note

参数与前面介绍的一致,故不做过多解释,且主模式暂时用不到。

5.4 输入捕获组合搭配

由于输入捕获牵扯到从模式以及其触发源,模式众多且有些模式需要特定触发源方能选择,所以单独列一节介绍模式如何搭配。

5.4.1 单输入捕获通道

实现基础结构,即单个输入捕获通道配合从模式自动清零CNT,结构图如下:

image-20241211221522415

那么在STM32CubeMX的配置流程如下:

image-20241212000507208

image-20241212000612755

上升沿触发,其他无需改,Input Filter为滤波器参数默认即可

image-20241212000759737

5.3.2 PWMI模式

实现PWMI结构,结构图如下:

image-20241211222427955

那么在STM32CubeMX的配置流程如下:

image-20241212001243494

image-20241212001335663

配置通道 2 参数:

image-20241212001420560

5.5 工程配置

5.5.1 单通道输入捕获

完成RCCSYS以及5.4中的单通道参数配置,另外需要完成时基单元配置,主要是选择计数最大值,以及测周法的标准频率选择

  • 选择TIM3的通道 1
  • 自动重装值选择最大值 65535 ,防止提前清零CNT
  • 预分频器选 72-1 ,让标准频率尽量大,这样一个方波周期可以记更多数,损失的时间越少。

应注意此时的标准频率为1MHZ,即一个数代表0.000001s。

image-20241212122917621

配置输入信号即PWM

  • 参考输出比较那一节
  • 频率自定义,注意ARR值计算占空比需要

image-20241213230155069

下面时代码正文:

打开输入比较和输入捕获定时器,注意代码位置应该软件配置的初始化(xxx_Init)之后。

C
/* USER CODE BEGIN 2 */
HAL_TIM_IC_Start_IT(&htim3, TIM_CHANNEL_1);
HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_1);
/* USER CODE END 2 */

我的OLED显示

C
// OLED静态显示
OLED_Init();
OLED_Clear();
OLED_ShowString(0, 0, "CCR1:00000", 16, 1);
OLED_ShowString(0, 2, "Freq:00000HZ", 16, 1);

While循环中写测量代码,HAL_TIM_ReadCapturedValue读取捕获计数值

\[ 频率=\frac{标准频率}{CCR1+1} \]
C
/* USER CODE BEGIN 3 */
value = HAL_TIM_ReadCapturedValue(&htim3, TIM_CHANNEL_1);
// TI1FP1
OLED_ShowNum(40, 0, value, 5, 16, 0);
OLED_ShowNum(40, 2, 1000000/(value+1), 5, 16, 0);
/* USER CODE END 3 */

5.5.2 PWMI模式

image-20241213231559442

image-20241213231628041

添加输入捕获通道 2 时钟,配置占空比,500/1000 即 50%

C
/* USER CODE BEGIN 2 */
HAL_TIM_IC_Start_IT(&htim3, TIM_CHANNEL_1);
HAL_TIM_IC_Start_IT(&htim3, TIM_CHANNEL_2);
HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_1);
__HAL_TIM_SetCompare(&htim2,TIM_CHANNEL_1, 500);
/* USER CODE END 2 */

我的OLED显示

C
// OLED静态显示
OLED_Init();
OLED_Clear();
OLED_ShowString(0, 0, "CCR1:00000", 16, 1);
OLED_ShowString(0, 2, "Freq:00000HZ", 16, 1);
OLED_ShowString(0, 4, "CCR2:00000", 16, 1);
OLED_ShowString(0, 6, "Duty:00000%", 16, 1);

While循环中添加通道 2 测量代码

\[ 占空比=\frac{CCR2+1}{CCR1+1} \]
C
/* USER CODE BEGIN 3 */
value = HAL_TIM_ReadCapturedValue(&htim3, TIM_CHANNEL_1);
value_h = HAL_TIM_ReadCapturedValue(&htim3, TIM_CHANNEL_2);
// TI1FP1
OLED_ShowNum(40, 0, value, 5, 16, 0);
OLED_ShowNum(40, 2, 1000000/(value+1), 5, 16, 0);
// TI1FP2
OLED_ShowNum(40, 4, value_h, 5, 16, 0);
OLED_ShowNum(40, 6, (value_h+1)*100 / (value+1), 5, 16, 0);
/* USER CODE END 3 */

5.5.3 捕获中断介绍

关于定时器中输入捕获/输出比较的中断函数,此为通道一,我们主要关注输入捕获部分即可:

  • 输入捕获的中断函数:HAL_TIM_IC_CaptureCallback()
  • 输出比较的中断函数:HAL_TIM_PWM_PulseFinishedCallback()

输出比较中断简单了解

C
/* Capture compare 1 event */
if ((itflag & (TIM_FLAG_CC1)) == (TIM_FLAG_CC1)) {
    if ((itsource & (TIM_IT_CC1)) == (TIM_IT_CC1)) {
        {
            __HAL_TIM_CLEAR_FLAG(htim, TIM_FLAG_CC1);
            htim->Channel = HAL_TIM_ACTIVE_CHANNEL_1;

            /* Input capture event */
            if ((htim->Instance->CCMR1 & TIM_CCMR1_CC1S) != 0x00U) {
                #if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
                htim->IC_CaptureCallback(htim);
                #else
                HAL_TIM_IC_CaptureCallback(htim);
                #endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
            }
            /* Output compare event */
            else {
                #if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
                htim->OC_DelayElapsedCallback(htim);
                htim->PWM_PulseFinishedCallback(htim);
                #else
                HAL_TIM_OC_DelayElapsedCallback(htim);
                HAL_TIM_PWM_PulseFinishedCallback(htim);
                #endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
            }
            htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED;
        }
    }
}

如果需要使用中断,在stm32f1xx_it.c文件下方重写输入捕获中断,当CNT转运到CCR寄存器时,触发改中断,此时我们读取CCR的值即可分析出输入信号的频率:

C
/* USER CODE BEGIN 1 */
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
    if (htim==&htim3)
    {
    }
}
/* USER CODE END 1 */