从上图可以看到输入捕获的配置流程,第一步就是配置GPIO口,以及复用。然后就是配置滤波器,这里的滤波器并不会改变信号频率,而是以非常高速的脉冲连续采样,当连续采样的电平都是一样的时候才会将信号发送给下面的电路。然后就是配置边沿检测,可以选择上升沿触发也可以选择下降沿触发。然后就是配置信号分路,是想要直连这一条路还是另外一条路。然后就是分频器的配置,对信号进行分频处理。最后就是CCR了,这里需要补充的是当信号进行触发时,电路会自动将计数器的值保存在ccr中。
如果我们只需要测量频率,就只需要配置一条直路即可。计算PWM波的频率只需要计算出两个上升沿或者下降沿间隔的时间即可,也就是测周法。如果我们同时需要测量频率和占空比,就需要配置两条支路了。一条负责测量频率一条负责测量占空比。代码如下所示:
void TIM4_PIN_Init(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_ICInitTypeDef TIM_ICInitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE); // 开启GPIOD时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); // 开启TIM4时钟
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; // 复用功能
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(GPIOD, &GPIO_InitStructure);
GPIO_PinAFConfig(GPIOD, GPIO_PinSource12, GPIO_AF_TIM4); // PD12 复用为 TIM4_CH1
// 设置定时器频率(84 MHz / 84 = 1 MHz,即 1 tick = 1us)
TIM_TimeBaseStructure.TIM_Prescaler = 84 - 1;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseStructure.TIM_Period = 0xFFFF; // 最大周期,防止溢出
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure);
// 配置输入捕获通道1(PD12)
TIM_ICInitStructure.TIM_Channel = TIM_Channel_1;
TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; // 上升沿
TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;//输入信号选择
TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; //分频系数
TIM_ICInitStructure.TIM_ICFilter = 0xF; //滤波系数
TIM_ICInit(TIM4, &TIM_ICInitStructure);
TIM_ICInitStructure.TIM_Channel = TIM_Channel_2;
TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Falling; // 下降沿
TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_IndirectTI;//输入信号选择
TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; //分频系数
TIM_ICInitStructure.TIM_ICFilter = 0xF; //滤波系数
TIM_ICInit(TIM4, &TIM_ICInitStructure);
TIM_SelectInputTrigger(TIM4,TIM_TS_TI1FP1); //触发源选择
TIM_SelectSlaveMode(TIM4,TIM_SlaveMode_Reset); //触发设备选择
// 启动定时器
TIM_Cmd(TIM4, ENABLE);
}
uint32_t get_Pin(void)
{
return 1000000/(TIM_GetCapture1(TIM4)+1);
}
uint32_t get_kong(void)
{
return (TIM_GetCapture2(TIM4)+1)*100/(TIM_GetCapture1(TIM4)+1);
}