概述
输入捕获模式可以用来测量脉冲宽度或者测量频率。STM32 的定时器,除了 TIM6 和 TIM7,其他定时器都有输入捕获功能。 STM32 的输入捕获,简单的说就是通过检测 TIMx_CHx 上的边沿信号,在边沿信号发生跳变(比如上升沿/下降沿)的时候,将当前定时器的值(TIMx_CNT)存放到对应的通道的捕获/比较寄存器(TIMx_CCRx)里面,完成一次捕获。同时还可以配置捕获时是否触发中断/DMA 等。
N是滤波长度 在检测到一次目标电平后再以采样频率连续采集N次如果N次结果都是相同则为一次有效触发每n次有效触发是视为一次有效捕获
捕获到后可以将通道1映射到通道2,或者从通道2映射到通道1(通道3、4同样 1、2不能映射到3、4上 同样3、4也不能映射到1、2上)
Fck_int是定时器的输入频率
Fdts是根据TIMx_CR1 的 CKD[1:0]的设置来确定的
流程
- 初始化相应时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
- 初始化GPIO
GPIOA_CAP_Init.GPIO_Mode=GPIO_Mode_IPU;
GPIOA_CAP_Init.GPIO_Pin=GPIO_Pin_0;
GPIOA_CAP_Init.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIOA_CAP_Init);
- 初始化定时器
TIM2_CAP_BaseInit.TIM_ClockDivision=TIM_CKD_DIV1;
TIM2_CAP_BaseInit.TIM_CounterMode=TIM_CounterMode_Up;
TIM2_CAP_BaseInit.TIM_Period=CAP_Period;
TIM2_CAP_BaseInit.TIM_Prescaler=CAP_Prescaler;
TIM_TimeBaseInit(TIM2,&TIM2_CAP_BaseInit);
- 初始化输入捕获IC参数
TIM2_CH1_ICInit.TIM_Channel=TIM_Channel_1;
TIM2_CH1_ICInit.TIM_ICFilter=0x00;
TIM2_CH1_ICInit.TIM_ICPolarity=TIM_ICPolarity_Rising;
TIM2_CH1_ICInit.TIM_ICPrescaler=TIM_ICPSC_DIV1;
TIM2_CH1_ICInit.TIM_ICSelection=TIM_ICSelection_DirectTI;
TIM_ICInit(TIM2,&TIM2_CH1_ICInit);
- 初始化中断并使能(如果需要)
NVIC_TIM2CH1_CAP_Init.NVIC_IRQChannel=TIM2_IRQn;
NVIC_TIM2CH1_CAP_Init.NVIC_IRQChannelCmd=ENABLE;
NVIC_TIM2CH1_CAP_Init.NVIC_IRQChannelPreemptionPriority=0;
NVIC_TIM2CH1_CAP_Init.NVIC_IRQChannelSubPriority=3;
NVIC_Init(&NVIC_TIM2CH1_CAP_Init);
TIM_ITConfig(TIM2,TIM_IT_Update | TIM_IT_CC1,ENABLE);
- 使能定时器
TIM_Cmd(TIM2,ENABLE);
- 编写中断服务函数
unsigned char TIM2CH1_CAP_STA=0;
unsigned short TIM2CH1_CAP_VAL=0;
void TIM2_IRQHandler()
{
if(TIM_GetITStatus(TIM2,TIM_IT_Update) == 1)
{
if(TIM2CH1_CAP_STA & 0x40)
{
if((TIM2CH1_CAP_STA & 0x3f) ==0x3f)
{
TIM2CH1_CAP_STA=0;
TIM2CH1_CAP_VAL=0xffff;
TIM_OC1PolarityConfig(TIM2,TIM_ICPolarity_Rising);
}
else TIM2CH1_CAP_STA++;
}
TIM_ClearITPendingBit(TIM2,TIM_IT_Update);
}
else if(TIM_GetITStatus(TIM2,TIM_IT_CC1)==1)
{
if((TIM2CH1_CAP_STA & 0x80) == 0)
{
if(TIM2CH1_CAP_STA&0x40)
{
USART_SendData(USART2,'b');
TIM2CH1_CAP_VAL=TIM_GetCapture1(TIM2);
TIM2CH1_CAP_STA |= 0x80;
TIM_OC1PolarityConfig(TIM2,TIM_ICPolarity_Rising);
}
else
{
TIM2CH1_CAP_STA =0;
TIM2CH1_CAP_STA |= 0x40;
TIM_SetCounter(TIM2,0);
TIM2CH1_CAP_VAL=0;
TIM_OC1PolarityConfig(TIM2,TIM_ICPolarity_Falling);
}
}
TIM_ClearITPendingBit(TIM2,TIM_IT_CC1);
}
}
中断服务函数流程图
备注
调整输入捕获极性时使用TIM_OC1PolarityConfig函数
没有TIM_IC1PolarityConfig 最终操作的都是同一个寄存器
且TIM_OCPolarity_Low和TIM_ICPolarity_Falling值相同