天天看點

有關STM32F4四路通道捕獲

最近玩32闆發現網上有關TIM定時器的四路通道捕獲高電平的内容很少,是以在此給出一個庫函數版本的,希望對大家有幫助。

void TIM3_Cap_Init(u32 arr,u16 psc)
{
	GPIO_InitTypeDef GPIO_InitStructure;
//		GPIO_InitTypeDef GPIO_InitStruct;
	TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
	NVIC_InitTypeDef NVIC_InitStructure;

	
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);  	//TIM5時鐘使能    
//	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE); 	//使能PORTA時鐘	
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); 
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE); 
	
	
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7; //GPIOA0
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//複用功能
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;	//速度100MHz
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽複用輸出
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN; //下拉
	GPIO_Init(GPIOA,&GPIO_InitStructure); //初始化PA0
	
	
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1; //GPIOA0
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//複用功能
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;	//速度100MHz
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽複用輸出
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN; //下拉
	GPIO_Init(GPIOB,&GPIO_InitStructure); //初始化PA0
	

//	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_15; //GPIOA0
//	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;//複用功能
//	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_100MHz;	//速度100MHz
//	GPIO_InitStruct.GPIO_OType = GPIO_OType_PP; //推挽複用輸出
//	GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_DOWN; //下拉
//	GPIO_Init(GPIOA,&GPIO_InitStruct); //初始化PA0

	GPIO_PinAFConfig(GPIOA,GPIO_PinSource6,GPIO_AF_TIM3); //PA0複用位定時器5
	GPIO_PinAFConfig(GPIOA,GPIO_PinSource7,GPIO_AF_TIM3);
	GPIO_PinAFConfig(GPIOB,GPIO_PinSource0,GPIO_AF_TIM3);
	GPIO_PinAFConfig(GPIOB,GPIO_PinSource1,GPIO_AF_TIM3);
  
	  
	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(TIM3,&TIM_TimeBaseStructure);
	

	//初始化TIM5輸入捕獲參數
	TIM3_ICInitStructure.TIM_Channel = TIM_Channel_1; //CC1S=01 	選擇輸入端 IC1映射到TI1上
  TIM3_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;	//上升沿捕獲
  TIM3_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; //映射到TI1上
  TIM3_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;	 //配置輸入分頻,不分頻 
  TIM3_ICInitStructure.TIM_ICFilter = 0x00;//IC1F=0000 配置輸入濾波器 不濾波
  TIM_ICInit(TIM3, &TIM3_ICInitStructure);
	
	TIM3_ICInitStructure.TIM_Channel = TIM_Channel_2;//CC1S=01 	選擇輸入端 IC1映射到TI1上
  TIM3_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;	//上升沿捕獲
  TIM3_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; //映射到TI1上
  TIM3_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;	 //配置輸入分頻,不分頻 
  TIM3_ICInitStructure.TIM_ICFilter = 0x00;//IC1F=0000 配置輸入濾波器 不濾波
  TIM_ICInit(TIM3, &TIM3_ICInitStructure);

	TIM3_ICInitStructure.TIM_Channel = TIM_Channel_3; //CC1S=01 	選擇輸入端 IC1映射到TI1上
  TIM3_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;	//上升沿捕獲
  TIM3_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; //映射到TI1上
  TIM3_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;	 //配置輸入分頻,不分頻 
  TIM3_ICInitStructure.TIM_ICFilter = 0x00;//IC1F=0000 配置輸入濾波器 不濾波
  TIM_ICInit(TIM3, &TIM3_ICInitStructure);
	
	TIM3_ICInitStructure.TIM_Channel = TIM_Channel_4; //CC1S=01 	選擇輸入端 IC1映射到TI1上
  TIM3_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;	//上升沿捕獲
  TIM3_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; //映射到TI1上
  TIM3_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;	 //配置輸入分頻,不分頻 
  TIM3_ICInitStructure.TIM_ICFilter = 0x00;//IC1F=0000 配置輸入濾波器 不濾波
  TIM_ICInit(TIM3, &TIM3_ICInitStructure);
	
	
	
	
	
	
		
	TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE);//允許更新中斷 ,允許CC1IE捕獲中斷	
	TIM_ITConfig(TIM3,TIM_IT_CC1,ENABLE);
	TIM_ITConfig(TIM3,TIM_IT_CC2,ENABLE);
	TIM_ITConfig(TIM3,TIM_IT_CC3,ENABLE);
	TIM_ITConfig(TIM3,TIM_IT_CC4,ENABLE);
  TIM_Cmd(TIM3,ENABLE ); 	//使能定時器5

 
  NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0;//搶占優先級3
	NVIC_InitStructure.NVIC_IRQChannelSubPriority =1;		//子優先級3
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;			//IRQ通道使能
	NVIC_Init(&NVIC_InitStructure);	//根據指定的參數初始化VIC寄存器、
	
	
	
	
	

	
}
//捕獲狀态
//[7]:0,沒有成功的捕獲;1,成功捕獲到一次.
//[6]:0,還沒捕獲到低電平;1,已經捕獲到低電平了.
//[5:0]:捕獲低電平後溢出的次數(對于32位定時器來說,1us計數器加1,溢出時間:4294秒)
u8  TIM3CH1_CAPTURE_STA=0;	//輸入捕獲狀态		    				
u32	TIM3CH1_CAPTURE_VAL;	//輸入捕獲值(TIM2/TIM5是32位)
u8  TIM3CH2_CAPTURE_STA=0;	//輸入捕獲狀态		    				
u32	TIM3CH2_CAPTURE_VAL;	//輸入捕獲值(TIM2/TIM5是32位)
u8  TIM3CH3_CAPTURE_STA=0;	//輸入捕獲狀态		    				
u32	TIM3CH3_CAPTURE_VAL;	//輸入捕獲值(TIM2/TIM5是32位)
u8  TIM3CH4_CAPTURE_STA=0;	//輸入捕獲狀态		    				
u32	TIM3CH4_CAPTURE_VAL;	//輸入捕獲值(TIM2/TIM5是32位)







//定時器5中斷服務程式	 
void TIM3_IRQHandler(void)
{ 		    

 	if((TIM3CH1_CAPTURE_STA&0X80)==0)//還未成功捕獲	
	{
		if(TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET)//溢出
		{	     
			if(TIM3CH1_CAPTURE_STA&0X40)//已經捕獲到高電平了
			{
				if((TIM3CH1_CAPTURE_STA&0X3F)==0X3F)//高電平太長了
				{
					TIM3CH1_CAPTURE_STA|=0X80;		//标記成功捕獲了一次
					TIM3CH1_CAPTURE_VAL=0XFFFFFFFF;
				}else TIM3CH1_CAPTURE_STA++;
			}	 
		}
		if(TIM_GetITStatus(TIM3, TIM_IT_CC1) != RESET)//捕獲1發生捕獲事件
		{	
			if(TIM3CH1_CAPTURE_STA&0X40)		//捕獲到一個下降沿 		
			{	  			
				TIM3CH1_CAPTURE_STA|=0X80;		//标記成功捕獲到一次高電平脈寬
			  TIM3CH1_CAPTURE_VAL=TIM_GetCapture1(TIM3);//擷取目前的捕獲值.
	 			TIM_OC1PolarityConfig(TIM3,TIM_ICPolarity_Rising); //CC1P=0 設定為上升沿捕獲
			}else  								//還未開始,第一次捕獲上升沿
			{
				TIM3CH1_CAPTURE_STA=0;			//清空
				TIM3CH1_CAPTURE_VAL=0;
				TIM3CH1_CAPTURE_STA|=0X40;		//标記捕獲到了上升沿
				TIM_Cmd(TIM3,DISABLE ); 	//關閉定時器5
	 			TIM_SetCounter(TIM3,0);
	 			TIM_OC1PolarityConfig(TIM3,TIM_ICPolarity_Falling);		//CC1P=1 設定為下降沿捕獲
				TIM_Cmd(TIM3,ENABLE ); 	//使能定時器5
			}		    
		}			     	    					   
 	}

	 	if((TIM3CH2_CAPTURE_STA&0X80)==0)//還未成功捕獲	
	{
		if(TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET)//溢出
		{	     
			if(TIM3CH2_CAPTURE_STA&0X40)//已經捕獲到高電平了
			{
				if((TIM3CH2_CAPTURE_STA&0X3F)==0X3F)//高電平太長了
				{
					TIM3CH2_CAPTURE_STA|=0X80;		//标記成功捕獲了一次
					TIM3CH2_CAPTURE_VAL=0XFFFFFFFF;
				}else TIM3CH2_CAPTURE_STA++;
			}	 
		}
		if(TIM_GetITStatus(TIM3, TIM_IT_CC2) != RESET)//捕獲1發生捕獲事件
		{	
			if(TIM3CH2_CAPTURE_STA&0X40)		//捕獲到一個下降沿 		
			{	  			
				TIM3CH2_CAPTURE_STA|=0X80;		//标記成功捕獲到一次高電平脈寬
			  TIM3CH2_CAPTURE_VAL=TIM_GetCapture2(TIM3);//擷取目前的捕獲值.
	 			TIM_OC2PolarityConfig(TIM3,TIM_ICPolarity_Rising); //CC1P=0 設定為上升沿捕獲
			}else  								//還未開始,第一次捕獲上升沿
			{
				TIM3CH2_CAPTURE_STA=0;			//清空
				TIM3CH2_CAPTURE_VAL=0;
				TIM3CH2_CAPTURE_STA|=0X40;		//标記捕獲到了上升沿
				TIM_Cmd(TIM3,DISABLE ); 	//關閉定時器5
	 			TIM_SetCounter(TIM3,0);
	 			TIM_OC2PolarityConfig(TIM3,TIM_ICPolarity_Falling);		//CC1P=1 設定為下降沿捕獲
				TIM_Cmd(TIM3,ENABLE ); 	//使能定時器5
			}		    
		}			     	    					   
 	}
	 	if((TIM3CH3_CAPTURE_STA&0X80)==0)//還未成功捕獲	
	{
		if(TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET)//溢出
		{	     
			if(TIM3CH3_CAPTURE_STA&0X40)//已經捕獲到高電平了
			{
				if((TIM3CH3_CAPTURE_STA&0X3F)==0X3F)//高電平太長了
				{
					TIM3CH3_CAPTURE_STA|=0X80;		//标記成功捕獲了一次
					TIM3CH3_CAPTURE_VAL=0XFFFFFFFF;
				}else TIM3CH3_CAPTURE_STA++;
			}	 
		}
		if(TIM_GetITStatus(TIM3, TIM_IT_CC3) != RESET)//捕獲1發生捕獲事件
		{	
			if(TIM3CH3_CAPTURE_STA&0X40)		//捕獲到一個下降沿 		
			{	  			
				TIM3CH3_CAPTURE_STA|=0X80;		//标記成功捕獲到一次高電平脈寬
			  TIM3CH3_CAPTURE_VAL=TIM_GetCapture3(TIM3);//擷取目前的捕獲值.
	 			TIM_OC3PolarityConfig(TIM3,TIM_ICPolarity_Rising); //CC1P=0 設定為上升沿捕獲
			}else  								//還未開始,第一次捕獲上升沿
			{
				TIM3CH3_CAPTURE_STA=0;			//清空
				TIM3CH3_CAPTURE_VAL=0;
				TIM3CH3_CAPTURE_STA|=0X40;		//标記捕獲到了上升沿
				TIM_Cmd(TIM3,DISABLE ); 	//關閉定時器5
	 			TIM_SetCounter(TIM3,0);
	 			TIM_OC3PolarityConfig(TIM3,TIM_ICPolarity_Falling);		//CC1P=1 設定為下降沿捕獲
				TIM_Cmd(TIM3,ENABLE ); 	//使能定時器5
			}		    
		}			     	    					   
 	}
	 	if((TIM3CH4_CAPTURE_STA&0X80)==0)//還未成功捕獲	
	{
		if(TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET)//溢出
		{	     
			if(TIM3CH4_CAPTURE_STA&0X40)//已經捕獲到高電平了
			{
				if((TIM3CH4_CAPTURE_STA&0X3F)==0X3F)//高電平太長了
				{
					TIM3CH4_CAPTURE_STA|=0X80;		//标記成功捕獲了一次
					TIM3CH4_CAPTURE_VAL=0XFFFFFFFF;
				}else TIM3CH4_CAPTURE_STA++;
			}	 
		}
		if(TIM_GetITStatus(TIM3, TIM_IT_CC4) != RESET)//捕獲1發生捕獲事件
		{	
			if(TIM3CH4_CAPTURE_STA&0X40)		//捕獲到一個下降沿 		
			{	  			
				TIM3CH4_CAPTURE_STA|=0X80;		//标記成功捕獲到一次高電平脈寬
			  TIM3CH4_CAPTURE_VAL=TIM_GetCapture4(TIM3);//擷取目前的捕獲值.
	 			TIM_OC4PolarityConfig(TIM3,TIM_ICPolarity_Rising); //CC1P=0 設定為上升沿捕獲
			}else  								//還未開始,第一次捕獲上升沿
			{
				TIM3CH4_CAPTURE_STA=0;			//清空
				TIM3CH4_CAPTURE_VAL=0;
				TIM3CH4_CAPTURE_STA|=0X40;		//标記捕獲到了上升沿
				TIM_Cmd(TIM3,DISABLE ); 	//關閉定時器5
	 			TIM_SetCounter(TIM3,0);
	 			TIM_OC4PolarityConfig(TIM3,TIM_ICPolarity_Falling);		//CC1P=1 設定為下降沿捕獲
				TIM_Cmd(TIM3,ENABLE ); 	//使能定時器5
			}		    
		}			     	    					   
 	}
	
		TIM_ClearITPendingBit(TIM3, TIM_IT_CC1|TIM_IT_Update|TIM_IT_CC2|TIM_IT_CC3|TIM_IT_CC4); //清除中斷标志位
	
           

  STM32F4中的TIMx定時器的功能十分強大,可以同時輸出四路PWM波,也可以同時四路采取高電平,及四路捕獲,如果在使用超音波傳感器時,可以使用,這樣的用法可以大大減少定時器的使用,雖然F4定時器很多,但是這種方法可以供大家參考參考。

  在TIM_ICInit函數中,TIM_Channel的選擇是對應的,是以在配置TIM_ICInit時不能用或“|”的邏輯符号。

繼續閱讀