stm32的TIMx捕获低频溢出问题

使用stm32的TIM4的通道1与通道2来主要实现捕获功能,低频是捕获值依旧准确。
环境使用的stm32f103vet6

一、贴出初始化部分的代码

void TIM4_Mode_Config(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
	TIM_ICInitTypeDef TIM_ICInitStructure;   
	NVIC_InitTypeDef NVIC_InitStructure;	
	
	//PB6 ch1  A,PB7 ch2 
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);     //使能TIM4时钟  
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);    //使能GPIOA时钟
	
	GPIO_StructInit(&GPIO_InitStructure);                //将GPIO_InitStruct中的参数按缺省值输入
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;         
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;    //PA6 PA7浮空输入  
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB, &GPIO_InitStructure);                           
	
	
	TIM_DeInit(TIM4);

	TIM_TimeBaseStructure.TIM_Period = TIM4_TIM_Period;//55999;根据个人需求进行配置       
	TIM_TimeBaseStructure.TIM_Prescaler = 0;  //预分频值
	TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;		//输入时钟不分频
	TIM_TimeBaseStructure.TIM_CounterMode =	TIM_CounterMode_Up; 	//向上计数
	TIM_TimeBaseInit(TIM4,&TIM_TimeBaseStructure);
	
	//输入捕捉方式
	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 = 0x3;          //捕捉输入滤波
	TIM_ICInit(TIM4, &TIM_ICInitStructure);
	TIM_ICInitStructure.TIM_Channel = TIM_Channel_2 ;
	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 = 0x3;          //捕捉输入滤波 0x0-0xF
	TIM_ICInit(TIM4, &TIM_ICInitStructure);				 

    TIM_ClearFlag(TIM4, TIM_IT_CC1 | TIM_IT_CC2| TIM_IT_Update);
    
	/* Enable the TIM4Interrupt */
	NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);	  

    TIM_ClearFlag(TIM4,TIM_FLAG_Update);
	TIM_ARRPreloadConfig(TIM4,DISABLE);
	
	/* Enable the CC2 Interrupt Request */
	TIM_ITConfig(TIM4, TIM_IT_CC1 | TIM_IT_CC2 | TIM_IT_Update , ENABLE);						
    /* TIM enable counter */
	TIM_Cmd(TIM4, ENABLE);
}

二、贴出中断处理函数,对于低频捕获必须要配置更新中断(TIM_IT_Update),当发生溢出中断时计数一次,最终算得的捕获时间需要加上(溢出次数*装载值),这样获得的低频捕获的值才是正确的。

void TIM4_IRQHandler(void)                        //定时器中断
{
	//频率缓冲区计数
	static u32 this_time_CH1 = 0;
	static u32 last_time_CH1 = 0;
	static u8 capture_number_CH1 = 0;
	vu32 tmp16_CH1;
	static u16 this_time_CH2 = 0;
	static u16 last_time_CH2 = 0;
	static u8 capture_number_CH2 = 0;
	vu32 tmp16_CH2;
		
	if (TIM_GetITStatus(TIM4,TIM_IT_Update) != RESET)       //计数器更新中断
	{
		  TIM_ClearITPendingBit(TIM4, TIM_IT_Update);
		  //溢出次数通道1、2分开统计
		  CH1_Cycles_Count++;
		  CH2_Cycles_Count++;
	}
	if(TIM_GetITStatus(TIM4, TIM_IT_CC1) != RESET)   //通道1脉冲检测中断
	{
			TIM_ClearITPendingBit(TIM4, TIM_IT_CC1);
			if(capture_number_CH1 == 0)                          //收到第一个上升沿
			{
				capture_number_CH1 = 1;
				last_time_CH1 = TIM_GetCapture1(TIM4);
			}
			else if(capture_number_CH1 == 1)                     //收到第二个上升沿
			{
				//capture_number_CH1 = 0;
				this_time_CH1 = TIM_GetCapture1(TIM4);
				if(this_time_CH1 > last_time_CH1)
				{
					tmp16_CH1 = this_time_CH1 - last_time_CH1 + TIM4_TIM_Period * CH1_Cycles_Count;
				}
				else
				{
					tmp16_CH1 = TIM4_TIM_Period * CH1_Cycles_Count - last_time_CH1 + this_time_CH1;
				}			
				CH1_Cycles_Count = 0;
				last_time_CH1 = this_time_CH1;	
			}							
	}
	if(TIM_GetITStatus(TIM4, TIM_IT_CC2) != RESET)      //通道2脉冲检测中断
	{
			TIM_ClearITPendingBit(TIM4, TIM_IT_CC2);
		    pulse_count++;
			if(capture_number_CH2 == 0)
			{
				capture_number_CH2 = 1;
				last_time_CH2 = TIM_GetCapture2(TIM4);
			}
			else if(capture_number_CH2 == 1)
			{
				//capture_number_CH2 = 0;
				this_time_CH2 = TIM_GetCapture2(TIM4);
				if(this_time_CH2 > last_time_CH2)
				{
					tmp16_CH2 = this_time_CH2 - last_time_CH2 + TIM4_TIM_Period * CH2_Cycles_Count;
				}
				else
				{
					tmp16_CH2 = TIM4_TIM_Period * CH2_Cycles_Count - last_time_CH2 + this_time_CH2;
				}
				CH2_Cycles_Count = 0;
				last_time_CH2 = this_time_CH2;
		    }
	}	
} 

三、注意事项
初始化部分就不说了,看到很多网友在捕获过程中存在问题。基本上大部分网友都是下图中“圈1”中没有屏蔽,“圈2”内容没有。这样的配置会造成丢失百分之五十的脉冲没有统计。大家自己体会一下下面的操作 。
在这里插入图片描述

  • 10
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值