我是靠谱客的博主 拉长篮球,最近开发中收集的这篇文章主要介绍stm32 单个定时器多路捕获测量频率与占空比(排坑),觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

单个定时器的多个通道可以捕获不同的方波信号

1.初始化配置

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;           //输入预分频。意思是控制在多少个输入周期做一次捕获,如果

//输入的信号频率没有变,测得的周期也不会变。比如选择4分频,则每四个输入周期才做一次捕获,这样在输入信号变化不频繁的情况下,

TIM_ICInitStructure.TIM_Channel = TIM_Channel_2; 

TIM_ICInitStructure.TIM_Channel = TIM_Channel_3; 

一定要分开写,切记不可TIM_ICInitStructure.TIM_Channel = TIM_Channel_2|TIM_Channel_3; 会出问题

2.原理

 先配置上升沿触发
TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;

位置一

清零CNT计数器TIM_SetCounter(TIM2,0);

并且设置下降沿触发

位置二

下降沿触发进入,捕获此时CNT IIM2_CH2ReadValue1 = TIM_GetCounter(TIM2); 

并且设置上升沿触发

位置三

上升沿触发进入,捕获此时CNT IIM2_CH2ReadValue2 = TIM_GetCounter(TIM2); 

此时利用IIM2_CH2ReadValue1,IIM2_CH2ReadValue2 计算频率占空比

循环进入位置一

两个通道需要交替进行捕获,否则由于一个TIM只有一个CNT计数器,第一个上升沿清零会混乱

这就需要另一个定时器计时分配捕获时间

if(capture_time>=100)//100ms
        {
         if(TIM_CaptureNumber==2)
             TIM_CaptureNumber=3;//通道三捕获
         else if(TIM_CaptureNumber==3)
             TIM_CaptureNumber=2;
            capture_time=0;//通道二捕获
      }    

 

下面以TIM2的CH2、CH3通道演示 

初始化代码 

__IO uint16_t IIM2_CH2ReadValue1 = 0, IIM2_CH2ReadValue2 = 0,
              IIM2_CH3ReadValue1 = 0, IIM2_CH3ReadValue2 = 0;
__IO uint16_t IIM2_CH2CaptureNumber = 0,IIM2_CH3CaptureNumber=0;
__IO uint32_t IIM2_CH2Freq = 0,IIM2_CH3Freq=0;
u8 TIM_CaptureNumber=2;

//__IO uint32_t Capture = 0;
//__IO uint32_t TIM2Freq = 0;

float TIM2_Duty2;
float TIM2_Duty3;

void pwm2_capture_init(void)
{ 
	TIM_ICInitTypeDef  TIM_ICInitStructure;
	GPIO_InitTypeDef GPIO_InitStructure;
  NVIC_InitTypeDef NVIC_InitStructure;

  /* Enable the TIM2 global Interrupt */
  NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
  /* TIM2 channel 2 pin (PA.01,02) configuration */
  GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_1|GPIO_Pin_2;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

  GPIO_Init(GPIOA, &GPIO_InitStructure);
	/* TIM2 clock enable */
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);

  /* GPIOA and GPIOB clock enable */
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	
	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 = 0x0;

  TIM_ICInit(TIM2, &TIM_ICInitStructure);
	
		TIM_ICInitStructure.TIM_Channel = TIM_Channel_3;//一定要与TIM_Channel_2分开写
    TIM_ICInit(TIM2, &TIM_ICInitStructure);
  /* TIM enable counter */
  TIM_Cmd(TIM2, ENABLE);

  /* Enable the CC2 Interrupt Request */
  TIM_ITConfig(TIM2, TIM_IT_CC2|TIM_IT_CC3, ENABLE);
	
}

 定时器中断捕获代码

void TIM2_IRQHandler(void)
{ 
  if(TIM_GetITStatus(TIM2, TIM_IT_CC2) == SET) 
  {
		
    /* Clear TIM2 Capture compare interrupt pending bit */
    TIM_ClearITPendingBit(TIM2, TIM_IT_CC2);
		if(TIM_CaptureNumber==2)
		{
				if(IIM2_CH2CaptureNumber == 0)
				{
					TIM_SetCounter(TIM2,0);
					TIM_OC2PolarityConfig(TIM2,TIM_ICPolarity_Falling);

					IIM2_CH2CaptureNumber = 1;
				}
				else if(IIM2_CH2CaptureNumber == 1)
				{
					/* Get the Input Capture value */
					IIM2_CH2ReadValue1 = TIM_GetCounter(TIM2); 
					TIM_OC2PolarityConfig(TIM2,TIM_ICPolarity_Rising);
					IIM2_CH2CaptureNumber=2;
				}
			 else if(IIM2_CH2CaptureNumber == 2)
				{
					/* Get the Input Capture value */
					IIM2_CH2ReadValue2 = TIM_GetCounter(TIM2); 
					IIM2_CH2Freq = (uint32_t)SystemCoreClock/IIM2_CH2ReadValue2;
					
					TIM2_Duty2= IIM2_CH2ReadValue1*100 /IIM2_CH2ReadValue2;
					IIM2_CH2CaptureNumber=0;
				}	
	  }
  }
	
	if(TIM_GetITStatus(TIM2, TIM_IT_CC3) == SET) 
  {
		
    /* Clear TIM2 Capture compare interrupt pending bit */
    TIM_ClearITPendingBit(TIM2, TIM_IT_CC3);
		if(TIM_CaptureNumber==3)
		{
				if(IIM2_CH3CaptureNumber == 0)
				{
					TIM_SetCounter(TIM2,0);
          TIM_OC3PolarityConfig(TIM2,TIM_ICPolarity_Falling);
					IIM2_CH3CaptureNumber = 1;
				}
				else if(IIM2_CH3CaptureNumber == 1)
				{
					/* Get the Input Capture value */
					IIM2_CH3ReadValue1 = TIM_GetCounter(TIM2); 
					TIM_OC3PolarityConfig(TIM2,TIM_ICPolarity_Rising);
					IIM2_CH3CaptureNumber=2;
				}
			  else if(IIM2_CH3CaptureNumber == 2)
				{
					/* Get the Input Capture value */
					IIM2_CH3ReadValue2 = TIM_GetCounter(TIM2); 
					IIM2_CH3Freq = (uint32_t)SystemCoreClock/IIM2_CH3ReadValue2;
					
					TIM2_Duty3= IIM2_CH3ReadValue1*100 /IIM2_CH3ReadValue2;
					IIM2_CH3CaptureNumber=0;
				}	
	  }
  }
}

定时器分配捕获时间 

void TIM4_IRQHandler(void)
{
	static u8 capture_time;
  if (TIM_GetITStatus(TIM4,TIM_IT_Update) != RESET)
  {
			capture_time++;
		if(capture_time>=100)//100ms
		{
		 if(TIM_CaptureNumber==2)
			 TIM_CaptureNumber=3;
		 else if(TIM_CaptureNumber==3)
			 TIM_CaptureNumber=2;
			capture_time=0;
	  }	
	
 }
}

 

 

最后

以上就是拉长篮球为你收集整理的stm32 单个定时器多路捕获测量频率与占空比(排坑)的全部内容,希望文章能够帮你解决stm32 单个定时器多路捕获测量频率与占空比(排坑)所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(40)

评论列表共有 0 条评论

立即
投稿
返回
顶部