第五章 输入捕获
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} $$
Note
高频适合使用测频法,低频适合使用测周法,而中界频率即使选择方法的临界频率。
5.1.3 输入捕获框图¶
下面是输入捕获的框架:
- 工作流程: 经过输入滤波器和极性选择进入预分频器,可以选择进行触发信号分频,然后触发信号进入捕获电路工作,每来一个触发信号,CNT的值向CCR转运一次,同时触发捕获事件,在状态寄存器置标志位触发中断,可以设置中断处理。
- 测周法实现: 以上升沿为触发信号,CNT计数器由内部标准时钟驱动(驱动时钟为\(\(f_c\)\) ),CNT数值即可记录两个上升沿的时间间隔,即为周期,取倒数可获得测周法的频率。
Note
每次捕获以后要将CNT清零,可以用主从触发模式自动完成。
通道 1 和 2 互相交叉捕获可以在定时器总框图看的更清楚:
5.2 主从触发模式¶
这个名字是从江协科技(以前叫江科大自化协)学来的。
5.2.1 主从触发模式简介¶
- 主模式:将定时器内部的信号映射到TRGO引脚,用于触发别的外设。
- 从模式:接收其他外设或自身外设的一些信号用于控制自身定时器的运行。(被其他信号控制)
5.2.2 主从模式选择¶
主模式各模式的信息,与表格中一一对应
从模式触发源选择
定时器的ITRx
引脚对应
从模式的模式选择,与表格中一一对应
5.3 输入捕获基本结构¶
5.3.1 基础结构¶
输入信号源可以自定义引脚输出一固定频率的方波,引脚接到输入捕获的引脚
执行逻辑如下:
- 输入信号源经过滤波,确定极性,上升沿或下降沿触发输入捕获
- 将CNT值写入CCR1寄存器
- 同时TI1FP1经过触发源选择,触发从模式 Reset自动清零CNT
5.3.2 PWMI模式¶
Warning
注意这里TI1FP2
并没有使用从模式,这是为了后面可以实现高电平单独测量,从而得出占空比的测量。
执行逻辑如下:
- 输入信号源经过滤波,确定极性, 让上升沿触发输入捕获 1 ,下降沿触发输入捕获 2
- 从第一个上升沿开始,经历第一个下降沿,将CNT值写入CCR2寄存器, 此时不会触发从模式清零CNT
- 经历第二个上升沿,将CNT值写入CCR1寄存器, 并触发从模式清零CNT
5.3.3 STM32CubeMX参数¶
各模式参数配置名称如下:
从模式选择:
- Slave mode :从模式,也可以选择配置为 外部时钟 1 。
- External Clock Mode 1:外部时钟模式 1
- Reset Mode:复位模式
- Gated Mode:门控模式
- Trigger Mode:触发模式
与前面的表格对应,具体功能上面有介绍,在此不重复。外部时钟模式 1 在定时中断同样介绍过。
触发源选择:
- Trigger mode :从模式触发源选择。
- ITR0
- ITR1
- ITR2
- ITR3
- ETR1(TIMx_ETR引脚)
- T1_ED
- T1FP1
- TI2FP2
Warning
具体如何配置组合达到想要的功能,会在后面介绍,此处先熟悉各个参数与前面理论部分的对应。
输入捕获的通道模式:
- 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时才可以选。
主模式参数选择:
Note
参数与前面介绍的一致,故不做过多解释,且主模式暂时用不到。
5.4 输入捕获组合搭配¶
由于输入捕获牵扯到从模式以及其触发源,模式众多且有些模式需要特定触发源方能选择,所以单独列一节介绍模式如何搭配。
5.4.1 单输入捕获通道¶
实现基础结构,即单个输入捕获通道配合从模式自动清零CNT,结构图如下:
那么在STM32CubeMX的配置流程如下:
上升沿触发,其他无需改,Input Filter
为滤波器参数默认即可
5.3.2 PWMI模式¶
实现PWMI结构,结构图如下:
那么在STM32CubeMX的配置流程如下:
配置通道 2 参数:
5.5 工程配置¶
5.5.1 单通道输入捕获¶
完成RCC
、SYS
以及5.4
中的单通道参数配置,另外需要完成时基单元配置,主要是选择计数最大值,以及测周法的标准频率选择
- 选择TIM3的通道 1
- 自动重装值选择最大值 65535 ,防止提前清零CNT
- 预分频器选 72-1 ,让标准频率尽量大,这样一个方波周期可以记更多数,损失的时间越少。
应注意此时的标准频率为1MHZ,即一个数代表0.000001s。
配置输入信号即PWM
- 参考输出比较那一节
- 频率自定义,注意ARR值计算占空比需要
下面时代码正文:
打开输入比较和输入捕获定时器,注意代码位置应该软件配置的初始化(xxx_Init)之后。
/* 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显示
// 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
读取捕获计数值
/* 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模式¶
添加输入捕获通道 2 时钟,配置占空比,500/1000 即 50%
/* 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显示
// 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 测量代码
/* 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()
输出比较中断简单了解
/* 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的值即可分析出输入信号的频率: