STM32 LL库 TIM3定时器多通道捕获输入采集

为什么不用HAL库,使用HAL库捕获输入一个通道还尚可,多通道捕获由于HAL的回调函数不符合我的要求,干脆直接切换到LL库。网上找了许多,代码处理写的不符合我的要求,这里记录一下我的调试过程。

TIM2输出1路PWM信号,使用1分3杜邦线接到TIM3的CH2-CH3-CH4通道进行捕获输入。

c 复制代码
#include "tim.h"

/* TIM2 init function */
void MX_TIM2_Init(void)
{

  LL_TIM_InitTypeDef TIM_InitStruct = {0};
  LL_TIM_OC_InitTypeDef TIM_OC_InitStruct = {0};

  LL_GPIO_InitTypeDef GPIO_InitStruct = {0};
  /* Peripheral clock enable */
  LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM2);


  TIM_InitStruct.Prescaler = 63;
  TIM_InitStruct.CounterMode = LL_TIM_COUNTERMODE_UP;
  TIM_InitStruct.Autoreload = 9999;
  TIM_InitStruct.ClockDivision = LL_TIM_CLOCKDIVISION_DIV1;
  LL_TIM_Init(TIM2, &TIM_InitStruct);
  LL_TIM_DisableARRPreload(TIM2);
  LL_TIM_SetClockSource(TIM2, LL_TIM_CLOCKSOURCE_INTERNAL);
  LL_TIM_OC_EnablePreload(TIM2, LL_TIM_CHANNEL_CH2);
  TIM_OC_InitStruct.OCMode = LL_TIM_OCMODE_PWM1;
  TIM_OC_InitStruct.OCState = LL_TIM_OCSTATE_DISABLE;
  TIM_OC_InitStruct.OCNState = LL_TIM_OCSTATE_DISABLE;
  TIM_OC_InitStruct.CompareValue = 5000;
  TIM_OC_InitStruct.OCPolarity = LL_TIM_OCPOLARITY_HIGH;
  LL_TIM_OC_Init(TIM2, LL_TIM_CHANNEL_CH2, &TIM_OC_InitStruct);
  LL_TIM_OC_DisableFast(TIM2, LL_TIM_CHANNEL_CH2);
  LL_TIM_SetTriggerOutput(TIM2, LL_TIM_TRGO_RESET);
  LL_TIM_DisableMasterSlaveMode(TIM2);
  /* USER CODE BEGIN TIM2_Init 2 */

  /* USER CODE END TIM2_Init 2 */
  LL_IOP_GRP1_EnableClock(LL_IOP_GRP1_PERIPH_GPIOB);
    /**TIM2 GPIO Configuration
    PB3     ------> TIM2_CH2
    */
  GPIO_InitStruct.Pin = LL_GPIO_PIN_3;
  GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
  GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW;
  GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
  GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
  GPIO_InitStruct.Alternate = LL_GPIO_AF_2;
  LL_GPIO_Init(GPIOB, &GPIO_InitStruct);
	
	//-------------------------------------------
	LL_TIM_OC_SetCompareCH2(TIM2,2000);
	LL_TIM_CC_EnableChannel(TIM2,LL_TIM_CHANNEL_CH2);
	LL_TIM_EnableCounter(TIM2);

}
/* TIM3 init function */
void MX_TIM3_Init(void)
{
  LL_TIM_InitTypeDef TIM_InitStruct = {0};

  LL_GPIO_InitTypeDef GPIO_InitStruct = {0};

  /* Peripheral clock enable */
  LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM3);

  LL_IOP_GRP1_EnableClock(LL_IOP_GRP1_PERIPH_GPIOA);
  LL_IOP_GRP1_EnableClock(LL_IOP_GRP1_PERIPH_GPIOB);
  /**TIM3 GPIO Configuration
  PA7   ------> TIM3_CH2
  PB0   ------> TIM3_CH3
  PB1   ------> TIM3_CH4
  */
  GPIO_InitStruct.Pin = LL_GPIO_PIN_7;
  GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
  GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW;
  GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
  GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
  GPIO_InitStruct.Alternate = LL_GPIO_AF_1;
  LL_GPIO_Init(GPIOA, &GPIO_InitStruct);

  GPIO_InitStruct.Pin = LL_GPIO_PIN_0;
  GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
  GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW;
  GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
  GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
  GPIO_InitStruct.Alternate = LL_GPIO_AF_1;
  LL_GPIO_Init(GPIOB, &GPIO_InitStruct);

  GPIO_InitStruct.Pin = LL_GPIO_PIN_1;
  GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
  GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW;
  GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
  GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
  GPIO_InitStruct.Alternate = LL_GPIO_AF_1;
  LL_GPIO_Init(GPIOB, &GPIO_InitStruct);

  /* TIM3 interrupt Init */
  NVIC_SetPriority(TIM3_IRQn, 0);
  NVIC_EnableIRQ(TIM3_IRQn);

  /* USER CODE BEGIN TIM3_Init 1 */

  /* USER CODE END TIM3_Init 1 */
  TIM_InitStruct.Prescaler = 63;
  TIM_InitStruct.CounterMode = LL_TIM_COUNTERMODE_UP;
  TIM_InitStruct.Autoreload = 65535;
  TIM_InitStruct.ClockDivision = LL_TIM_CLOCKDIVISION_DIV1;
  LL_TIM_Init(TIM3, &TIM_InitStruct);
  LL_TIM_DisableARRPreload(TIM3);
  LL_TIM_SetClockSource(TIM3, LL_TIM_CLOCKSOURCE_INTERNAL);
  LL_TIM_SetTriggerOutput(TIM3, LL_TIM_TRGO_RESET);
  LL_TIM_DisableMasterSlaveMode(TIM3);
	
  LL_TIM_IC_SetActiveInput(TIM3, LL_TIM_CHANNEL_CH2, LL_TIM_ACTIVEINPUT_DIRECTTI);
  LL_TIM_IC_SetPrescaler(TIM3, LL_TIM_CHANNEL_CH2, LL_TIM_ICPSC_DIV1);
  LL_TIM_IC_SetFilter(TIM3, LL_TIM_CHANNEL_CH2, LL_TIM_IC_FILTER_FDIV1);
  LL_TIM_IC_SetPolarity(TIM3, LL_TIM_CHANNEL_CH2, LL_TIM_IC_POLARITY_RISING);
	
  LL_TIM_IC_SetActiveInput(TIM3, LL_TIM_CHANNEL_CH3, LL_TIM_ACTIVEINPUT_DIRECTTI);
  LL_TIM_IC_SetPrescaler(TIM3, LL_TIM_CHANNEL_CH3, LL_TIM_ICPSC_DIV1);
  LL_TIM_IC_SetFilter(TIM3, LL_TIM_CHANNEL_CH3, LL_TIM_IC_FILTER_FDIV1);
  LL_TIM_IC_SetPolarity(TIM3, LL_TIM_CHANNEL_CH3, LL_TIM_IC_POLARITY_RISING);
	
  LL_TIM_IC_SetActiveInput(TIM3, LL_TIM_CHANNEL_CH4, LL_TIM_ACTIVEINPUT_DIRECTTI);
  LL_TIM_IC_SetPrescaler(TIM3, LL_TIM_CHANNEL_CH4, LL_TIM_ICPSC_DIV1);
  LL_TIM_IC_SetFilter(TIM3, LL_TIM_CHANNEL_CH4, LL_TIM_IC_FILTER_FDIV1);
  LL_TIM_IC_SetPolarity(TIM3, LL_TIM_CHANNEL_CH4, LL_TIM_IC_POLARITY_RISING);
	
  /* USER CODE BEGIN TIM3_Init 2 */
   LL_TIM_EnableIT_UPDATE(TIM3);//更新中断使能
   LL_TIM_EnableIT_CC2(TIM3);//捕获通道2使能
	 LL_TIM_EnableIT_CC3(TIM3);//捕获通道3使能
	 LL_TIM_EnableIT_CC4(TIM3);//捕获通道4使能
   LL_TIM_CC_EnableChannel(TIM3,LL_TIM_CHANNEL_CH2);//通道2使能
	 LL_TIM_CC_EnableChannel(TIM3,LL_TIM_CHANNEL_CH3);//通道3使能
	 LL_TIM_CC_EnableChannel(TIM3,LL_TIM_CHANNEL_CH4);//通道4使能
   LL_TIM_EnableCounter(TIM3);
 
  /* USER CODE END TIM3_Init 2 */

}



uint32_t  TIM3_OverCnt = 0;
int32_t  Value_Temp2 = 0;
int32_t  Value_Temp3 = 0;
int32_t  Value_Temp4 = 0;

uint32_t  TIM3_CH2_Capture_FristValue_1; 
uint32_t  TIM3_CH2_Capture_FristValue_2; 
uint32_t  TIM3_CH2_Capture_FristValue_3; 
uint32_t  TIM3_CH2_Capture_HighLevel; 
uint32_t  TIM3_CH2_Capture_LowLevel; 
uint8_t   TIM3_CH2_CaptureNumber;
//uint32_t  TIM3_CH2_Freq = 0;
//float 	  TIM3_CH2_Duty = 0;

uint32_t  TIM3_CH3_Capture_FristValue_1; 
uint32_t  TIM3_CH3_Capture_FristValue_2; 
uint32_t  TIM3_CH3_Capture_FristValue_3; 
uint32_t  TIM3_CH3_Capture_HighLevel; 
uint32_t  TIM3_CH3_Capture_LowLevel; 
uint8_t   TIM3_CH3_CaptureNumber;
//uint32_t  TIM3_CH3_Freq = 0;
//float 	  TIM3_CH3_Duty = 0;


uint32_t  TIM3_CH4_Capture_FristValue_1; 
uint32_t  TIM3_CH4_Capture_FristValue_2; 
uint32_t  TIM3_CH4_Capture_FristValue_3; 
uint32_t  TIM3_CH4_Capture_HighLevel; 
uint32_t  TIM3_CH4_Capture_LowLevel; 
uint8_t   TIM3_CH4_CaptureNumber;


void TIM3_CallBack(void)
{	
	//------------------------------------------CC2
		if(LL_TIM_IsActiveFlag_CC2(TIM3))
		{		
			 LL_TIM_ClearFlag_CC2(TIM3);
			
				if(TIM3_CH2_CaptureNumber == 0)
				{
						TIM3_OverCnt = 0;
						TIM3_CH2_CaptureNumber = 1;	
//					  LL_TIM_SetCounter(TIM3,0);	
				}
				else
					if(TIM3_CH2_CaptureNumber == 1)
					{	
						TIM3_CH2_Capture_FristValue_1 = LL_TIM_IC_GetCaptureCH2(TIM3);	// 获取当前的捕获值. 即CCRx2  
						//设置下降沿触发
						LL_TIM_IC_SetPolarity(TIM3,LL_TIM_CHANNEL_CH2,LL_TIM_IC_POLARITY_FALLING);						
						TIM3_CH2_CaptureNumber = 2;
						TIM3_OverCnt = 0;						
						
					}
					else
						if(TIM3_CH2_CaptureNumber == 2)
						{
							TIM3_CH2_Capture_FristValue_2 = LL_TIM_IC_GetCaptureCH2(TIM3);	// 获取当前的捕获值. 即CCRx2  
							if(TIM3_OverCnt >= 1)
							{								 						
								TIM3_CH2_Capture_HighLevel = TIM3_OverCnt * 65535 + TIM3_CH2_Capture_FristValue_2 - TIM3_CH2_Capture_FristValue_1;			
							}
							else
							{
								Value_Temp2 = TIM3_CH2_Capture_FristValue_2 - TIM3_CH2_Capture_FristValue_1;
								Value_Temp2 = Value_Temp2>0?Value_Temp2:0;							
								TIM3_CH2_Capture_HighLevel = TIM3_OverCnt * 65535 + Value_Temp2;
							}											
							//设置上升沿触发
							LL_TIM_IC_SetPolarity(TIM3,LL_TIM_CHANNEL_CH2,LL_TIM_IC_POLARITY_RISING);		
							TIM3_CH2_CaptureNumber = 3;
							TIM3_OverCnt = 0;
						}
					else
						if(TIM3_CH2_CaptureNumber == 3)
						{
							TIM3_CH2_Capture_FristValue_3 = LL_TIM_IC_GetCaptureCH2(TIM3);	// 获取当前的捕获值. 即CCRx2  
							
							if(TIM3_OverCnt >= 1)
							{
								TIM3_CH2_Capture_LowLevel = TIM3_OverCnt * 65535 + TIM3_CH2_Capture_FristValue_3 - TIM3_CH2_Capture_FristValue_2;							
							}
							else
							{
								Value_Temp2 = TIM3_CH2_Capture_FristValue_3 - TIM3_CH2_Capture_FristValue_2;
								Value_Temp2 = Value_Temp2>0?Value_Temp2:0;
								TIM3_CH2_Capture_LowLevel = TIM3_OverCnt * 65535 + Value_Temp2;							
							}
		//					//设置    沿触发
							LL_TIM_IC_SetPolarity(TIM3,LL_TIM_CHANNEL_CH2,LL_TIM_IC_POLARITY_FALLING);				
							TIM3_CH2_CaptureNumber = 4;
							TIM3_OverCnt = 0;
						}		
					else
						if(TIM3_CH2_CaptureNumber == 4)
						{
		//					//设置    沿触发
							LL_TIM_IC_SetPolarity(TIM3,LL_TIM_CHANNEL_CH2,LL_TIM_IC_POLARITY_RISING);				
							TIM3_CH2_CaptureNumber = 1;
							TIM3_OverCnt = 0;
						}					
		}		
	//------------------------------------------CC3
		if(LL_TIM_IsActiveFlag_CC3(TIM3))
		{	
			 LL_TIM_ClearFlag_CC3(TIM3);

				if(TIM3_CH3_CaptureNumber == 0)
				{
						TIM3_OverCnt = 0;
						TIM3_CH3_CaptureNumber = 1;	
//					  LL_TIM_SetCounter(TIM3,0);	
				}
				else
					if(TIM3_CH3_CaptureNumber == 1)
					{
						TIM3_OverCnt = 0;
					
						TIM3_CH3_Capture_FristValue_1 = LL_TIM_IC_GetCaptureCH3(TIM3);	// 获取当前的捕获值. 即CCRx2  
						//设置下降沿触发
						LL_TIM_IC_SetPolarity(TIM3,LL_TIM_CHANNEL_CH3,LL_TIM_IC_POLARITY_FALLING);						
						TIM3_CH3_CaptureNumber = 2;					
					}
					else
						if(TIM3_CH3_CaptureNumber == 2)
						{
							TIM3_CH3_Capture_FristValue_2 = LL_TIM_IC_GetCaptureCH3(TIM3);	// 获取当前的捕获值. 即CCRx2  
							if(TIM3_OverCnt >= 1)
							{			
								TIM3_CH3_Capture_HighLevel = TIM3_OverCnt * 65535 + TIM3_CH3_Capture_FristValue_2 - TIM3_CH3_Capture_FristValue_1;							
							}	
							else
							{
								Value_Temp3 = TIM3_CH3_Capture_FristValue_2 - TIM3_CH3_Capture_FristValue_1;
								Value_Temp3 = Value_Temp3>0?Value_Temp3:0;						
								TIM3_CH3_Capture_HighLevel = TIM3_OverCnt * 65535 + Value_Temp3;
							}	

							//设置上升沿触发
							LL_TIM_IC_SetPolarity(TIM3,LL_TIM_CHANNEL_CH3,LL_TIM_IC_POLARITY_RISING);			
							TIM3_CH3_CaptureNumber = 3;
							TIM3_OverCnt = 0;
						}
					else
						if(TIM3_CH3_CaptureNumber == 3)
						{
							TIM3_CH3_Capture_FristValue_3 = LL_TIM_IC_GetCaptureCH3(TIM3);	// 获取当前的捕获值. 即CCRx2  
							if(TIM3_OverCnt >= 1)
							{					
								TIM3_CH3_Capture_LowLevel = TIM3_OverCnt * 65535 + TIM3_CH3_Capture_FristValue_3 - TIM3_CH3_Capture_FristValue_2;								
							}	
							else
							{
								Value_Temp3 = TIM3_CH3_Capture_FristValue_3 - TIM3_CH3_Capture_FristValue_2;
								Value_Temp3 = Value_Temp3>0?Value_Temp3:0;							
								TIM3_CH3_Capture_LowLevel = TIM3_OverCnt * 65535 + Value_Temp3;
							}	

		//					//设置    沿触发
							LL_TIM_IC_SetPolarity(TIM3,LL_TIM_CHANNEL_CH3,LL_TIM_IC_POLARITY_FALLING);	
							TIM3_CH3_CaptureNumber = 4;
							TIM3_OverCnt = 0;
						}		
					else
						if(TIM3_CH3_CaptureNumber == 4)
						{
		//					//设置    沿触发
							LL_TIM_IC_SetPolarity(TIM3,LL_TIM_CHANNEL_CH3,LL_TIM_IC_POLARITY_RISING);		
							TIM3_CH3_CaptureNumber = 1;
							TIM3_OverCnt = 0;
						}				
		}
	//------------------------------------------CC4
		if(LL_TIM_IsActiveFlag_CC4(TIM3))
		{	
			 LL_TIM_ClearFlag_CC4(TIM3);

				if(TIM3_CH4_CaptureNumber == 0)
				{
						TIM3_OverCnt = 0;
						TIM3_CH4_CaptureNumber = 1;	
//					   LL_TIM_SetCounter(TIM3,0);	
				}
				else
					if(TIM3_CH4_CaptureNumber == 1)
					{
						TIM3_OverCnt = 0;
					
						TIM3_CH4_Capture_FristValue_1 = LL_TIM_IC_GetCaptureCH4(TIM3);	// 获取当前的捕获值. 即CCRx2  
						//设置下降沿触发
						LL_TIM_IC_SetPolarity(TIM3,LL_TIM_CHANNEL_CH4,LL_TIM_IC_POLARITY_FALLING);			
						TIM3_CH4_CaptureNumber = 2;
						
					}
					else
						if(TIM3_CH4_CaptureNumber == 2)
						{
							TIM3_CH4_Capture_FristValue_2 = LL_TIM_IC_GetCaptureCH4(TIM3);	// 获取当前的捕获值. 即CCRx2  
							if(TIM3_OverCnt >= 1)
							{					
								TIM3_CH4_Capture_HighLevel = TIM3_OverCnt * 65535 + TIM3_CH4_Capture_FristValue_2 - TIM3_CH4_Capture_FristValue_1;								
							}	
							else
							{
								Value_Temp4 = TIM3_CH4_Capture_FristValue_2 - TIM3_CH4_Capture_FristValue_1;
								Value_Temp4 = Value_Temp4>0?Value_Temp4:0;							
								TIM3_CH4_Capture_HighLevel = TIM3_OverCnt * 65535 + Value_Temp4;
							}	

							//设置上升沿触发
							LL_TIM_IC_SetPolarity(TIM3,LL_TIM_CHANNEL_CH4,LL_TIM_IC_POLARITY_RISING);			
							TIM3_CH4_CaptureNumber = 3;
							TIM3_OverCnt = 0;
						}
					else
						if(TIM3_CH4_CaptureNumber == 3)
						{
							TIM3_CH4_Capture_FristValue_3 = LL_TIM_IC_GetCaptureCH4(TIM3);	// 获取当前的捕获值. 即CCRx2  
							if(TIM3_OverCnt >= 1)
							{									
								TIM3_CH4_Capture_LowLevel = TIM3_OverCnt * 65535 + TIM3_CH4_Capture_FristValue_3 - TIM3_CH4_Capture_FristValue_2; 								
							}	
							else
							{
								Value_Temp4 = TIM3_CH4_Capture_FristValue_3 - TIM3_CH4_Capture_FristValue_2;
								Value_Temp4 = Value_Temp4>0?Value_Temp4:0;							
								TIM3_CH4_Capture_LowLevel = TIM3_OverCnt * 65535 + Value_Temp4; 
							}	

		//					//设置    沿触发
							LL_TIM_IC_SetPolarity(TIM3,LL_TIM_CHANNEL_CH4,LL_TIM_IC_POLARITY_FALLING);	
							TIM3_CH4_CaptureNumber = 4;
							TIM3_OverCnt = 0;
						}		
					else
						if(TIM3_CH4_CaptureNumber == 4)
						{
		//					//设置    沿触发
							LL_TIM_IC_SetPolarity(TIM3,LL_TIM_CHANNEL_CH4,LL_TIM_IC_POLARITY_RISING);		
							TIM3_CH4_CaptureNumber = 1;
							TIM3_OverCnt = 0;
							
						}				
		} 
 	
		
		
 	//------------------------------------------Update
		if(LL_TIM_IsActiveFlag_UPDATE(TIM3))
		{	
			LL_TIM_ClearFlag_UPDATE(TIM3); //每次溢出时间为65536us
			TIM3_OverCnt++;
		}
				

		 
}
c 复制代码
#ifndef __TIM_H__
#define __TIM_H__

#ifdef __cplusplus
extern "C" {
#endif

/* Includes ------------------------------------------------------------------*/
#include "main.h"


void MX_TIM2_Init(void);
void MX_TIM3_Init(void);
void TIM3_CallBack(void);


#ifdef __cplusplus
}
#endif

#endif /* __TIM_H__ */
c 复制代码
#include "main.h"
#include "tim.h"
#include "gpio.h"

 
void SystemClock_Config(void);
 
int main(void)
{
 
  HAL_Init();

 
  SystemClock_Config();

 
  MX_GPIO_Init();
  MX_TIM2_Init();
  MX_TIM3_Init();
 
  while (1)
  {
 
  }
 
}
c 复制代码
/**
  * @brief This function handles TIM3 global interrupt.
  */
void TIM3_IRQHandler(void)
{
 
	TIM3_CallBack();
 
}
相关推荐
智者知已应修善业27 分钟前
【51单片机用数码管显示流水灯的种类是按钮控制数码管加一和流水灯】2022-6-14
c语言·经验分享·笔记·单片机·嵌入式硬件·51单片机
智商偏低7 小时前
单片机之helloworld
单片机·嵌入式硬件
青牛科技-Allen8 小时前
GC3910S:一款高性能双通道直流电机驱动芯片
stm32·单片机·嵌入式硬件·机器人·医疗器械·水泵、
森焱森10 小时前
无人机三轴稳定控制(2)____根据目标俯仰角,实现俯仰稳定化控制,计算出升降舵输出
c语言·单片机·算法·架构·无人机
白鱼不小白10 小时前
stm32 USART串口协议与外设(程序)——江协教程踩坑经验分享
stm32·单片机·嵌入式硬件
S,D11 小时前
MCU引脚的漏电流、灌电流、拉电流区别是什么
驱动开发·stm32·单片机·嵌入式硬件·mcu·物联网·硬件工程
芯岭技术13 小时前
PY32F002A单片机 低成本控制器解决方案,提供多种封装
单片机·嵌入式硬件
youmdt14 小时前
Arduino IDE ESP8266连接0.96寸SSD1306 IIC单色屏显示北京时间
单片机·嵌入式硬件
嘿·嘘14 小时前
第七章 STM32内部FLASH读写
stm32·单片机·嵌入式硬件
Meraki.Zhang14 小时前
【STM32实践篇】:I2C驱动编写
stm32·单片机·iic·驱动·i2c