一、简介:
1.名称:
IC,输入捕获
2.电路:
如图为通用定时器框图,下半部分的左半模块,与输出比较部分共用捕获/比较寄存器与引脚。
3.功能:
当通道输入引脚出现电平跳变时,当前CNT的值,写入CCR中。
4.框图:
信号先进入滤波器,其中ICF寄存器为滤波器参数,数值越大,滤波效果越好
随后进入边沿检测器,用于检测上升沿和下降沿,随后CC1P寄存器,可控制极性。
随后信号来到一个数据选择器,可选择输出到捕获/比较寄存器1的信号来自通道1还是通道2,实际上,输入通道1.2与寄存器1.2是交叉的,即通道1的信号可以同时传给寄存器1和2,通道2也可以。
寄存器ICPS位,用于控制分频器,CC1E位,用于控制输出使能或失能。
主从触发模式:注意到TI1FP1信号,可以链接到从模式控制器,接下来介绍。
5.主从触发模式:
主模式:定时器信号,通过TRGO引脚,控制其他外设。
从模式:外来信号,通过TRGI引脚,控制定时器。
二、频率测量方法:
1.测频法:在闸门时间T内,对上升沿计次为N,f = N/T,适用高频信号
2.测周法,在两个上升沿内,以标准频率fc计次,得到N,f = fc/N,适用低频信号
三、实战:频率测量
1.思路:
运用测周法测频率,让CNT以一定频率计数,当上升沿到来后,CNT的数值记录到CCR中,随后将CNT清零(使用主从触发模式,触发源选择TI1FP1,从模式选择Reset功能)。
CCR的值,就是N,CNT的时钟频率,就是fc,f = fc/N。
2.功能图:
3.代码:IC.c
用PA0输出PWM信号,用PA6(定时器3的通道1)做输入捕获。
#include "stm32f10x.h" // Device header/*** 函 数:输入捕获初始化* 参 数:无* 返 回 值:无*/
void IC_Init(void)
{/*开启时钟*/RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //开启TIM3的时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //开启GPIOA的时钟/*GPIO初始化*/GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure); //将PA6引脚初始化为上拉输入/*配置时钟源*/TIM_InternalClockConfig(TIM3); //选择TIM3为内部时钟,若不调用此函数,TIM默认也为内部时钟/*时基单元初始化*/TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure; //定义结构体变量TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1; //时钟分频,选择不分频,此参数用于配置滤波器时钟,不影响时基单元功能TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up; //计数器模式,选择向上计数TIM_TimeBaseInitStructure.TIM_Period = 65536 - 1; //计数周期,即ARR的值,越大越好TIM_TimeBaseInitStructure.TIM_Prescaler = 72 - 1; //预分频器,即PSC的值,此处1MHzTIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0; //重复计数器,高级定时器才会用到TIM_TimeBaseInit(TIM3, &TIM_TimeBaseInitStructure); //将结构体变量交给TIM_TimeBaseInit,配置TIM3的时基单元/*输入捕获初始化*/TIM_ICInitTypeDef TIM_ICInitStructure; //定义结构体变量TIM_ICInitStructure.TIM_Channel = TIM_Channel_1; //选择配置定时器通道1TIM_ICInitStructure.TIM_ICFilter = 0xF; //输入滤波器参数,可以过滤信号抖动TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; //极性,选择为上升沿触发捕获TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; //捕获预分频,选择不分频,每次信号都触发捕获TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; //输入信号交叉,选择直通,不交叉TIM_ICInit(TIM3, &TIM_ICInitStructure); //将结构体变量交给TIM_ICInit,配置TIM3的输入捕获通道/*选择触发源及从模式*/TIM_SelectInputTrigger(TIM3, TIM_TS_TI1FP1); //触发源选择TI1FP1TIM_SelectSlaveMode(TIM3, TIM_SlaveMode_Reset); //从模式选择复位//即TI1产生上升沿时,会触发CNT归零/*TIM使能*/TIM_Cmd(TIM3, ENABLE); //使能TIM3,定时器开始运行
}/*** 函 数:获取输入捕获的频率* 参 数:无* 返 回 值:捕获得到的频率*/
uint32_t IC_GetFreq(void)
{return 1000000 / (TIM_GetCapture1(TIM3) + 1); //测周法得到频率fx = fc / N,这里不执行+1的操作也可
}
四、实战:占空比测量
1.PWMI模式:
两个通道,同时捕获一个引脚,一个配置为上升沿触发, 另一个配置为下降沿触发,即可同时测量频率与占空比,占空比=CCR1/CCR2。
2.功能图:
3.代码:新IC.c
#include "stm32f10x.h" // Device header/*** 函 数:输入捕获初始化* 参 数:无* 返 回 值:无*/
void IC_Init(void)
{/*开启时钟*/RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //开启TIM3的时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //开启GPIOA的时钟/*GPIO初始化*/GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure); //将PA6引脚初始化为上拉输入/*配置时钟源*/TIM_InternalClockConfig(TIM3); //选择TIM3为内部时钟,若不调用此函数,TIM默认也为内部时钟/*时基单元初始化*/TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure; //定义结构体变量TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1; //时钟分频,选择不分频,此参数用于配置滤波器时钟,不影响时基单元功能TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up; //计数器模式,选择向上计数TIM_TimeBaseInitStructure.TIM_Period = 65536 - 1; //计数周期,即ARR的值TIM_TimeBaseInitStructure.TIM_Prescaler = 72 - 1; //预分频器,即PSC的值TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0; //重复计数器,高级定时器才会用到TIM_TimeBaseInit(TIM3, &TIM_TimeBaseInitStructure); //将结构体变量交给TIM_TimeBaseInit,配置TIM3的时基单元/*PWMI模式初始化*/TIM_ICInitTypeDef TIM_ICInitStructure; //定义结构体变量TIM_ICInitStructure.TIM_Channel = TIM_Channel_1; //选择配置定时器通道1TIM_ICInitStructure.TIM_ICFilter = 0xF; //输入滤波器参数,可以过滤信号抖动TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; //极性,选择为上升沿触发捕获TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; //捕获预分频,选择不分频,每次信号都触发捕获TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; //输入信号交叉,选择直通,不交叉TIM_PWMIConfig(TIM3, &TIM_ICInitStructure); //将结构体变量交给TIM_PWMIConfig,配置TIM3的输入捕获通道//此函数同时会把另一个通道配置为相反的配置,实现PWMI模式/*选择触发源及从模式*/TIM_SelectInputTrigger(TIM3, TIM_TS_TI1FP1); //触发源选择TI1FP1TIM_SelectSlaveMode(TIM3, TIM_SlaveMode_Reset); //从模式选择复位//即TI1产生上升沿时,会触发CNT归零/*TIM使能*/TIM_Cmd(TIM3, ENABLE); //使能TIM3,定时器开始运行
}/*** 函 数:获取输入捕获的频率* 参 数:无* 返 回 值:捕获得到的频率*/
uint32_t IC_GetFreq(void)
{return 1000000 / (TIM_GetCapture1(TIM3) + 1); //测周法得到频率fx = fc / N,这里不执行+1的操作也可
}/*** 函 数:获取输入捕获的占空比* 参 数:无* 返 回 值:捕获得到的占空比*/
uint32_t IC_GetDuty(void)
{return (TIM_GetCapture2(TIM3) + 1) * 100 / (TIM_GetCapture1(TIM3) + 1); //占空比Duty = CCR2 / CCR1 * 100,这里不执行+1的操作也可
}