stm32f4 PWM捕获 (上升沿/下降沿/高低电平时间)详解(含代码)

最近毕业设计又需要实现一个小功能,使用PWM捕获到一个信号的上升沿,并在这个信号的上升沿进行一些操作

一开始我有尝试过读取管脚的高低电平,但是由于这个信号的速度过快,高低电平是读取不到的,只能采用PWM捕获的方式,其实也比较好操作!

与以往需要两个通道来进行PWM捕获不同,这个代码只需要一个通道就可以实现

首先依然是PWM捕获的配置,代码如下:

TIM_ICInitTypeDef  TIM5_ICInitStructure;


void TIM5_CH2_Cap_Init(u32 arr,u16 psc)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
	NVIC_InitTypeDef NVIC_InitStructure;
	TIM_ICInitTypeDef  TIM5_ICInitStructure;

	
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5,ENABLE);  	   
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); 		
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; //修改IO口
	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_DOWN; 
	GPIO_Init(GPIOA,&GPIO_InitStructure); 

	GPIO_PinAFConfig(GPIOA,GPIO_PinSource1,GPIO_AF_TIM5); 
  
	  
	TIM_TimeBaseStructure.TIM_Prescaler=psc; 
	TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; 
	TIM_TimeBaseStructure.TIM_Period=arr;   
	TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1; 
	
	TIM_TimeBaseInit(TIM5,&TIM_TimeBaseStructure);
	
	
	
	
	TIM5_ICInitStructure.TIM_Channel = TIM_Channel_2;  //修改通道
  TIM5_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;	
  TIM5_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; 
  TIM5_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV2;	
  TIM5_ICInitStructure.TIM_ICFilter = 0x00;
  TIM_ICInit(TIM5, &TIM5_ICInitStructure);
		
	TIM_ITConfig(TIM5,TIM_IT_Update|TIM_IT_CC2,ENABLE);	//通道对应着CC几
	
  TIM_Cmd(TIM5,ENABLE ); 	
 
  NVIC_InitStructure.NVIC_IRQChannel = TIM5_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority =0;		
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;			
	NVIC_Init(&NVIC_InitStructure);	
	
	
}


u32  TIM5CH2_CAPTURE_STA=0;			    				
u32	TIM5CH2_CAPTURE_VAL;
 

void TIM5_IRQHandler(void)
{ 		    
 	if((TIM5CH2_CAPTURE_STA&0X80)==0)	
	{
		if(TIM_GetITStatus(TIM5, TIM_IT_Update) != RESET)	
		{	     
			if(TIM5CH2_CAPTURE_STA&0X40)					
			{
				if((TIM5CH2_CAPTURE_STA&0X3F)==0X3F)
				{
					TIM5CH2_CAPTURE_STA|=0X80;				
					TIM5CH2_CAPTURE_VAL=0XFFFFFFFF;
				}
				else
					TIM5CH2_CAPTURE_STA++;
			}	 
		}
		if(TIM_GetITStatus(TIM5, TIM_IT_CC2) != RESET)
		{	
			if(TIM5CH2_CAPTURE_STA&0X40)				
			{	  			
				TIM5CH2_CAPTURE_STA|=0X80;				
			    TIM5CH2_CAPTURE_VAL=TIM_GetCapture2(TIM5);//修改通道	
	 			TIM_Cmd(TIM5,DISABLE ); 					
			    TIM_SetCounter(TIM5,0);						
			}else  													
			{
				TIM5CH2_CAPTURE_STA=0;				
				TIM5CH2_CAPTURE_VAL=0;
				TIM5CH2_CAPTURE_STA|=0X40;		
				TIM_Cmd(TIM5,ENABLE ); 
			}		    
		}			     	    					   
 	}
	TIM_ClearITPendingBit(TIM5, TIM_IT_CC2|TIM_IT_Update); 
}

比较需要注意的是,除了基本的IO口修改,PWM捕获一共4个通道,还需要根据使用的IO口定义自己的通道,我这里用的是TIM5的2通道,对应着stm32f4的话是PA1

配置完成之后,TIM5CH2_CAPTURE_STA==0x40的时候,就是上升沿的时刻了

如果想要捕获下降沿,配置的时候TIM5_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;  就修改成下降沿

这里还需要注意的一点是,STA和VAL都需要定义成extern

extern u32  TIM5CH2_CAPTURE_STA;			    				
extern u32	TIM5CH2_CAPTURE_VAL;	

在main里面,配置PWM捕获的速度

int main(void)
{ 
	
			TIM5_CH2_Cap_Init(0XFFFFFFFF,84-1);  //1M

	while(1)
	{ 
		
		if(TIM5CH2_CAPTURE_STA&0X80)        
		{
			temp=TIM5CH2_CAPTURE_STA&0X3F; 
			temp*=0XFFFFFFFF;		 		         
			temp+=TIM5CH2_CAPTURE_VAL;				
			

			TIM5CH2_CAPTURE_STA=0;			     
		}
    }
}

如果想要获取PWM的高低电平时间,就需要定义temp,在这里temp是高电平的时间,如果想要获取低电平时间,前面配置成获取低电平就行了

之后,我们将进行PWM捕获的管脚(这里是PA1),连接到需要进行PWM捕获的信号管脚上(而不是用输出信号的管脚直接去PWM捕获)。我只需要获取高电平,在debug里面,我们可以看到STA会0x40--0x00不断变化,说明捕获成功

你可能感兴趣的:(stm32,单片机,arm)