蓝桥杯嵌入式STM32定时器PWM输出、PWM捕获

  • 这里以stm32F103RBT6为例

单个定时器输出多路相同频率不同占空比的方波

void TIM2_PWM_Init(void)
{
	TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
	TIM_OCInitTypeDef  TIM_OCInitStructure;
	GPIO_InitTypeDef GPIO_InitStructure;
	uint16_t PrescalerValue = 0;
	uint16_t CCR1_Val = 500;
	
	/* TIM2 clock enable */
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
	/* GPIOA  clock enable */
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);

	GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_1|GPIO_Pin_2;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	/* Compute the prescaler value */
	PrescalerValue = (uint16_t) (SystemCoreClock / 1000000) - 1;
	/* Time base configuration */
	TIM_TimeBaseStructure.TIM_Period = 1000 - 1;
	TIM_TimeBaseStructure.TIM_Prescaler = PrescalerValue;
	TIM_TimeBaseStructure.TIM_ClockDivision = 0;
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;

	TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);

	/* PWM1 Mode configuration: Channel2 */
	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;					
	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;		
	TIM_OCInitStructure.TIM_Pulse = CCR1_Val;							
	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;			
	TIM_OC2Init(TIM2, &TIM_OCInitStructure);
	TIM_OC2PreloadConfig(TIM2, TIM_OCPreload_Enable);
	
	/* PWM1 Mode configuration: Channel3 */
	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;					
	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;		
	TIM_OCInitStructure.TIM_Pulse = CCR1_Val;							
	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;			
	TIM_OC3Init(TIM2, &TIM_OCInitStructure);
	TIM_OC3PreloadConfig(TIM2, TIM_OCPreload_Enable);

	TIM_ARRPreloadConfig(TIM2, ENABLE);

	/* TIM2 enable counter */
	TIM_Cmd(TIM2, ENABLE);
}

TIM_SetAutoreload(TIM2,1000 - 1);	//设置TIM2的重载值,PWM频率1kHZ
TIM_SetCompare2(TIM2,500);		//设置占空比,50%
TIM_SetCompare3(TIM2,100);		//设置占空比,10%

单个定时器输出多路不同频率不同占空比的方波

__IO uint16_t TIM2_CCR2_Val = 8192;
__IO uint16_t TIM2_CCR3_Val = 4096;

void TIM2_PWM_OCToggle(void)
{
  NVIC_InitTypeDef NVIC_InitStructure;
  TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
  TIM_OCInitTypeDef  TIM_OCInitStructure;
  GPIO_InitTypeDef GPIO_InitStructure;
  uint16_t PrescalerValue = 0;

  /* System Clocks Configuration */
  /* TIM2 clock enable */
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);

  /* GPIOA clock enable */
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB|
                         RCC_APB2Periph_GPIOC | RCC_APB2Periph_AFIO, ENABLE);

  /* NVIC Configuration */
  /* 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);

  /* GPIO Configuration */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

  GPIO_Init(GPIOA, &GPIO_InitStructure);
  /* ---------------------------------------------------------------------------
    TIM2 Configuration: Output Compare Toggle Mode:
    TIM2CLK = SystemCoreClock / 2,
    The objective is to get TIM2 counter clock at 12 MHz:
     - Prescaler = (TIM2CLK / TIM2 counter clock) - 1
    CC1 update rate = TIM2 counter clock / CCR1_Val = 366.2 Hz
    CC2 update rate = TIM2 counter clock / CCR2_Val = 732.4 Hz
    CC3 update rate = TIM2 counter clock / CCR3_Val = 1464.8 Hz
    CC4 update rate = TIM2 counter clock / CCR4_Val = 2929.6 Hz
  ----------------------------------------------------------------------------*/
  /* Compute the prescaler value */
  PrescalerValue = (uint16_t) (SystemCoreClock / 24000000) - 1;

  /* Time base configuration */
  TIM_TimeBaseStructure.TIM_Period = 65535;
  TIM_TimeBaseStructure.TIM_Prescaler = PrescalerValue;
  TIM_TimeBaseStructure.TIM_ClockDivision = 0;
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;

  TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);

  /* Output Compare Toggle Mode configuration: Channel2 */
  TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Toggle;
  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
  TIM_OCInitStructure.TIM_Pulse = TIM2_CCR2_Val;
  TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;
  TIM_OC2Init(TIM2, &TIM_OCInitStructure);

  TIM_OC2PreloadConfig(TIM2, TIM_OCPreload_Disable);

  /* Output Compare Toggle Mode configuration: Channel3 */
  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
  TIM_OCInitStructure.TIM_Pulse = TIM2_CCR3_Val;

  TIM_OC3Init(TIM2, &TIM_OCInitStructure);

  TIM_OC3PreloadConfig(TIM2, TIM_OCPreload_Disable);

  /* TIM enable counter */
  TIM_Cmd(TIM2, ENABLE);
  
  /* TIM IT enable */
  TIM_ITConfig(TIM2, TIM_IT_CC2 | TIM_IT_CC3 , ENABLE);
}

uint16_t TIM2_capture = 0;
_Bool TIM2_CH2_flag=0, TIM2_CH3_flag=0;
float TIM2_CH2_duty=0.3, TIM2_CH3_duty=0.7;
void TIM2_IRQHandler(void)
{
	/* TIM2_CH2 toggling with frequency = 732.4 Hz */
	if (TIM_GetITStatus(TIM2, TIM_IT_CC2) != RESET)
	{
		TIM_ClearITPendingBit(TIM2, TIM_IT_CC2 );
		TIM2_capture = TIM_GetCapture2(TIM2);
		if(TIM2_CH2_flag==1)
		{
			TIM_SetCompare2(TIM2, TIM2_capture + (u16)(TIM2_CCR2_Val*TIM2_CH2_duty));
			TIM2_CH2_flag=0;
		}
		else
		{
			TIM_SetCompare2(TIM2, TIM2_capture + (u16)(TIM2_CCR2_Val*(1-TIM2_CH2_duty)));
			TIM2_CH2_flag=1;
		}
	}

  /* TIM2_CH3 toggling with frequency = 1464.8 Hz */
  if (TIM_GetITStatus(TIM2, TIM_IT_CC3) != RESET)
  {
    TIM_ClearITPendingBit(TIM2, TIM_IT_CC3);
    TIM2_capture = TIM_GetCapture3(TIM2);
	if(TIM2_CH3_flag==1)
	{
		TIM_SetCompare3(TIM2, TIM2_capture + (u16)(TIM2_CCR3_Val*TIM2_CH3_duty));
		TIM2_CH3_flag=0;
	}
	else
	{
		TIM_SetCompare3(TIM2, TIM2_capture + (u16)(TIM2_CCR3_Val*(1-TIM2_CH3_duty)));
		TIM2_CH3_flag=1;
	}
  }
}

单个定时器捕获多路不同频率的方波

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

	
	/* TIM3 clock enable */
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);

	/* GPIOA and GPIOB clock enable */
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	
	/* Enable the TIM3 global Interrupt */
	NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStructure);
	
	
	/* TIM3 channel 2 pin (PA.07) configuration */
	GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_6 | GPIO_Pin_7;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	/* TIM3 configuration: Input Capture mode ---------------------
     The external signal is connected to TIM3 CH2 pin (PA.07)  
     The Rising edge is used as active edge,
     The TIM3 CCR2 is used to compute the frequency value 
	------------------------------------------------------------ */

	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(TIM3, &TIM_ICInitStructure);
	
	TIM_ICInitStructure.TIM_Channel = TIM_Channel_1;
	TIM_ICInit(TIM3, &TIM_ICInitStructure);

	/* TIM enable counter */
	TIM_Cmd(TIM3, ENABLE);

	/* Enable the CC1 / CC2 Interrupt Request */
	TIM_ITConfig(TIM3,TIM_IT_CC1|TIM_IT_CC2, ENABLE);
}

__IO uint16_t TIM3_CH2_ReadValue1 = 0, TIM3_CH2_ReadValue2 = 0;
__IO uint16_t TIM3_CH2_CaptureNumber = 0;
__IO uint32_t TIM3_CH2_Capture = 0;
__IO uint32_t TIM3_CH2_Freq = 0;

__IO uint16_t TIM3_CH1_ReadValue1 = 0, TIM3_CH1_ReadValue2 = 0;
__IO uint16_t TIM3_CH1_CaptureNumber = 0;
__IO uint32_t TIM3_CH1_Capture = 0;
__IO uint32_t TIM3_CH1_Freq = 0;

void TIM3_IRQHandler(void)
{ 
  if(TIM_GetITStatus(TIM3, TIM_IT_CC2) == SET) 
  {
    /* Clear TIM3 Capture compare interrupt pending bit */
    TIM_ClearITPendingBit(TIM3, TIM_IT_CC2);
    if(TIM3_CH2_CaptureNumber == 0)
    {
      /* Get the Input Capture value */
      TIM3_CH2_ReadValue1 = TIM_GetCapture2(TIM3);
      TIM3_CH2_CaptureNumber = 1;
    }
    else if(TIM3_CH2_CaptureNumber == 1)
    {
      /* Get the Input Capture value */
      TIM3_CH2_ReadValue2 = TIM_GetCapture2(TIM3); 
      
      /* Capture computation */
      if (TIM3_CH2_ReadValue2 > TIM3_CH2_ReadValue1)
      {
       TIM3_CH2_Capture = (TIM3_CH2_ReadValue2 - TIM3_CH2_ReadValue1); 
      }
      else
      {
        TIM3_CH2_Capture = ((0xFFFF - TIM3_CH2_ReadValue1) + TIM3_CH2_ReadValue2); 
      }
      /* Frequency computation */ 
      TIM3_CH2_Freq = (uint32_t) SystemCoreClock / TIM3_CH2_Capture;
      TIM3_CH2_CaptureNumber = 0;
    }
  }
  
  if(TIM_GetITStatus(TIM3, TIM_IT_CC1) == SET) 
  {
    /* Clear TIM3 Capture compare interrupt pending bit */
    TIM_ClearITPendingBit(TIM3, TIM_IT_CC1);
	if(TIM3_CH1_CaptureNumber == 0)
    {
      /* Get the Input Capture value */
      TIM3_CH1_ReadValue1 = TIM_GetCapture1(TIM3);
      TIM3_CH1_CaptureNumber = 1;
    }
    else if(TIM3_CH1_CaptureNumber == 1)
    {
      /* Get the Input Capture value */
      TIM3_CH1_ReadValue2 = TIM_GetCapture1(TIM3); 
      
      /* Capture computation */
      if (TIM3_CH1_ReadValue2 > TIM3_CH1_ReadValue1)
      {
       TIM3_CH1_Capture = (TIM3_CH1_ReadValue2 - TIM3_CH1_ReadValue1); 
      }
      else
      {
        TIM3_CH1_Capture = ((0xFFFF - TIM3_CH1_ReadValue1) + TIM3_CH1_ReadValue2); 
      }
      /* Frequency computation */ 
      TIM3_CH1_Freq = (uint32_t) SystemCoreClock / TIM3_CH1_Capture;
      TIM3_CH1_CaptureNumber = 0;
    }
  }
}

单个定时器捕获多路方波的频率和占空比

void TIM3_Input_Mode_Init(void)
{
	NVIC_InitTypeDef NVIC_InitStructure;
	GPIO_InitTypeDef GPIO_InitStructure;
	TIM_ICInitTypeDef  TIM_ICInitStructure;
	
	/* TIM3 clock enable */
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);

	/* GPIOA and GPIOB clock enable */
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	
	/* Enable the TIM3 global Interrupt */
	NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStructure);
	
	
	/* TIM3 channel 2 pin (PA.07) configuration */
	GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_6 | GPIO_Pin_7;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

	GPIO_Init(GPIOA, &GPIO_InitStructure);
	/* TIM3 configuration: Input Capture mode ---------------------
     The external signal is connected to TIM3 CH2 pin (PA.07)  
     The Rising edge is used as active edge,
     The TIM3 CCR2 is used to compute the frequency value 
	------------------------------------------------------------ */

	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(TIM3, &TIM_ICInitStructure);
	
	TIM_ICInitStructure.TIM_Channel = TIM_Channel_1;
	TIM_ICInit(TIM3, &TIM_ICInitStructure);

	/* TIM enable counter */
	TIM_Cmd(TIM3, ENABLE);

	/* Enable the CC1 / CC2 Interrupt Request */
	TIM_ITConfig(TIM3,TIM_IT_CC1|TIM_IT_CC2, ENABLE);
}

__IO uint16_t TIM3_CH2_ReadValue1 = 0, TIM3_CH2_ReadValue2 = 0;
__IO uint16_t TIM3_CH2_CaptureNumber = 0;
__IO uint32_t TIM3_CH2_Freq = 0;

__IO uint16_t TIM3_CH1_ReadValue1 = 0, TIM3_CH1_ReadValue2 = 0;
__IO uint16_t TIM3_CH1_CaptureNumber = 0;
__IO uint32_t TIM3_CH1_Freq = 0;
u8 TIM3_CH1_Duty, TIM3_CH2_Duty;

u8 capture_flag = 1;
void TIM3_IRQHandler(void)
{
  if(TIM_GetITStatus(TIM3, TIM_IT_CC2) == SET) 
  {
    /* Clear TIM3 Capture compare interrupt pending bit */
    TIM_ClearITPendingBit(TIM3, TIM_IT_CC2);
		if(capture_flag == 2)
		{
			if(TIM3_CH2_CaptureNumber == 0)
			{
				TIM_SetCounter(TIM3, 0);
				TIM_OC2PolarityConfig(TIM3,TIM_ICPolarity_Falling);
				TIM3_CH2_CaptureNumber = 1;
			}
			else if (TIM3_CH2_CaptureNumber == 1)
			{
				/* Get the Input Capture value */
				TIM3_CH2_ReadValue1 = TIM_GetCounter(TIM3);
				TIM_OC2PolarityConfig(TIM3,TIM_ICPolarity_Rising);
				TIM3_CH2_CaptureNumber = 2;
			}
			else if(TIM3_CH2_CaptureNumber == 2)
			{
				/* Get the Input Capture value */
				TIM3_CH2_ReadValue2 = TIM_GetCounter(TIM3); 
				/* Frequency computation */ 
				TIM3_CH2_Freq = (uint32_t) SystemCoreClock / TIM3_CH2_ReadValue2;
				TIM3_CH2_Duty = TIM3_CH2_ReadValue1 * 100 / TIM3_CH2_ReadValue2;
				TIM3_CH2_CaptureNumber = 0;
			}
		} 
  }
  
  if(TIM_GetITStatus(TIM3, TIM_IT_CC1) == SET) 
  {
    /* Clear TIM3 Capture compare interrupt pending bit */
    TIM_ClearITPendingBit(TIM3, TIM_IT_CC1);
	if(capture_flag == 1)
	{
		if(TIM3_CH1_CaptureNumber == 0)
		{
			TIM_SetCounter(TIM3, 0);
			TIM_OC1PolarityConfig(TIM3,TIM_ICPolarity_Falling);
			TIM3_CH1_CaptureNumber = 1;
		}
		else if (TIM3_CH1_CaptureNumber == 1)
		{
			 /* Get the Input Capture value */
			TIM3_CH1_ReadValue1 = TIM_GetCounter(TIM3);
			TIM_OC1PolarityConfig(TIM3,TIM_ICPolarity_Rising);
			TIM3_CH1_CaptureNumber = 2;
		}
		else if(TIM3_CH1_CaptureNumber == 2)
		{
		  /* Get the Input Capture value */
		  TIM3_CH1_ReadValue2 = TIM_GetCounter(TIM3); 
		  
		  /* Frequency computation */ 
		  TIM3_CH1_Freq = (uint32_t) SystemCoreClock / TIM3_CH1_ReadValue2;
		  TIM3_CH1_Duty = TIM3_CH1_ReadValue1 * 100 / TIM3_CH1_ReadValue2;
		  TIM3_CH1_CaptureNumber = 0;
		}  
	}
  }
}
//利用滴答定时器进行100ms捕获一个通道
static u16 pwm_capture_count=0;		
if(++pwm_capture_count==100)
{
	pwm_capture_count=0;
	capture_flag = capture_flag % 2 + 1;
	TIM3_CH1_CaptureNumber=0;
	TIM3_CH2_CaptureNumber=0;
}

你可能感兴趣的:(STM32)