Timer输入捕获的使用


一、输入捕获的介绍

通用定时器具有多种功能,输入捕获就是其中一种。STM32F1 除了基本定时器 ,其他定时器都具有输入捕获功能。输入捕获可以对输入的信号的上升沿,下降沿或者双边沿进行捕获,通常用于测量输入信号的脉宽、测量 PWM 输入信号的频率及占空比。

输入捕获的工作原理是:在输入捕获模式下,当相应的 IC 信号检测到信号的变换后,将使用捕获/比较寄存器(TIMx_CCRx)来锁存计数器的值。简单的说就是通过检测 TIMx_CHx 上的边沿信号,在边沿信号发生跳变(比如上升沿/下降沿)的时候,将当前定时器的值(TIMx_CNT)存放到对应的通道的捕获/比较寄存(TIMx_CCRx)里面,完成一次捕获。同时还可以配置捕获时是否触发中断/DMA 等。下面我们以输入捕获测量脉宽为例,通过一个简图来介绍输入捕获的工作原理,


 

 从上图可以看出,t1-t2 时间就是需要测量的高电平时间,假如定时器工作在向上计数模式,测量方法是:首先设置定时器通道 1为上升沿捕获,这样在 t1 时刻,就会捕获到当前的 CNT 值,记录为CCRx1,然后立即清零 CNT,并设置通道 2为下降沿捕获,这样到 t2 时刻,又会发生捕获事件,得到此时的 CNT 值,记为 CCRx2。根据定时器的计数频率,我们就可以算出 t1-t2 的时间,得到高电平脉宽。在 t1-t2 时间内可能会出现 N 次定时器溢出,因此我们还需要对定时器溢出进行处理,防止因高电平时间过长发生溢出导致测量数据不准。CNT计数的次数等于:N*ARR+CCRx2,有了这个计数次数,再乘以 CNT 的计数周期,即可得到 t2-t1 的时间长度,即高电平持续时间。

图1:

 而相比输出比较(OC):输入捕获是截取外部信号变化(电平跳变),把计数值(CNT)的保存到捕获/比较寄存器(CCR)中,而输出比较是依据计数值(CNT)和捕获/比较寄存器(CCR)来输出电平值(高电平/低电平),所以输出比较可以进行PWM波的生成和信号的生成,输入捕获可以测量信号的频率。

二、输入捕获配置步骤

图2:

 由图1和图2可得:信号从TIMx_CH1通道进入经过滤波器,边沿检测器后进行分频处理,由从模式控制计数值(CNT)的存储。

1.使能定时器和端口时钟,并设置引脚模式

RCC_APB1PeriphClockCmd()//进行定时器使能
RCC_APB2PeriphClockCmd();//进行端口时钟使能

//GPIO的基本配置
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = ;
GPIO_InitStructure.GPIO_Pin = ;
GPIO_InitStructure.GPIO_Speed =;
GPIO_Init();
	

2.时基单元的配置和输入捕获基本配置

TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
TIM_TimeBaseInitStruct.TIM_ClockDivision=; //分频系数
TIM_TimeBaseInitStruct.TIM_CounterMode=; //计数模式
//定时器频率 = 72M/(重装载值+1)/(预分频值+1)
TIM_TimeBaseInitStruct.TIM_Period= ;  //重装载值
TIM_TimeBaseInitStruct.TIM_Prescaler= //预分频
TIM_TimeBaseInitStruct.TIM_RepetitionCounter=;
TIM_TimeBaseInit();

三、代码案例

所要实现的功能是:按键不按下的时候是低电平(GPIO中配置了上拉输入模式)使用TIM2的CH1检测按键按下的高电平时间, 将检测的高电平脉宽时间通过OLED显示屏显示出来

 由此图可以看出,按键不按下的时候,PA0所检测的为低电平,也就是图1点。按键按下时,PA0口检测跳变为高电平(上升沿),输入捕获开始收集高电平时间。当按键松手的时候,PA0口检测电平跳变为低电平(下降沿),输入捕获停止收集高点平时间。

理论想法是这样的,因此需要定时器进行输入捕获,用中断来控制输入捕获的开始和结束,然后oled屏能够时刻记录高电平显示时间。

1,定时器2的输入捕获通道1配置

void timer_gpio_config(void)
{
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
	TIM_InternalClockConfig(TIM2);//内部时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
	TIM_TimeBaseInitStruct.TIM_ClockDivision=TIM_CKD_DIV1;
	TIM_TimeBaseInitStruct.TIM_CounterMode=TIM_CounterMode_Up;
	//定时器频率 = 72M/(重装载值+1)/(预分频值+1)
	TIM_TimeBaseInitStruct.TIM_Period= 10000 - 1;   
	TIM_TimeBaseInitStruct.TIM_Prescaler= 7200 - 1; //10000HZ 0.0001秒
	TIM_TimeBaseInitStruct.TIM_RepetitionCounter=0;
	TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStruct);	
	
	TIM_ICInitTypeDef TIM_ICInitStructure;
	TIM_ICInitStructure.TIM_Channel = TIM_Channel_1;
	TIM_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(TIM2, &TIM_ICInitStructure);
	
	TIM_ITConfig(TIM2,TIM_IT_Update|TIM_IT_CC1,ENABLE);
	
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	NVIC_InitTypeDef NVIC_InitStruct;
	NVIC_InitStruct.NVIC_IRQChannel=TIM2_IRQn;
	NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE;
	NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=2;
	NVIC_InitStruct.NVIC_IRQChannelSubPriority=2;
	NVIC_Init(&NVIC_InitStruct);
	
	TIM_Cmd(TIM2,ENABLE);
	
	
	
}

2.OLED用的是江科大的模板。

3.中断函数,能够实时显示高电平时间

void TIM2_IRQHandler(void)
{

		if(TIM_GetITStatus(TIM2,TIM_IT_CC1)==SET&&Falling_Flag==0){   		
			Capture1_Count=0;
			TIM_ClearITPendingBit(TIM2,TIM_IT_CC1);
			TIM_SetCounter(TIM2,0);
			Falling_Flag=1;
			TIM_OC1PolarityConfig(TIM2,TIM_OCPolarity_High);
		}
		
		if(TIM_GetITStatus(TIM2,TIM_IT_CC1)==RESET&&Falling_Flag==1){
			
			if(TIM_GetITStatus(TIM2,TIM_IT_Update)==SET){
				Spill_Count++;  						
			}
			Capture1_Count=(TIM_GetCapture1(TIM2)+Spill_Count*10000)/10;
		}
		
		if(TIM_GetITStatus(TIM2,TIM_IT_CC1)==SET&&Falling_Flag==1){    
			Capture1_Count=(TIM_GetCapture1(TIM2)+Spill_Count*10000)/10;//得到最终的计数值(原本记一个数是0.1ms,现在把单位转换为1ms)
			Spill_Count=0;
			TIM_SetCounter(TIM2,0);
			Falling_Flag=0;    
			TIM_OC1PolarityConfig(TIM2,TIM_OCPolarity_Low);       
		}
		OLED_ShowNum(3,1,Capture1_Count/1000,4);
		OLED_ShowNum(3,6,Capture1_Count%100,2);
		OLED_ShowNum(4,12,Spill_Count,2);

		TIM_ClearITPendingBit(TIM2,TIM_IT_Update|TIM_IT_CC1);

}

总结

对于定时器输入捕获,除了单个定时器进行输入捕获,也可以设置主从模式进行定时器中断控制。输入捕获大致用于信号的获取和利用。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值