Embedded Blue Bridge Cup PWM input capture

First we confirm that the output PWM pin is
Insert picture description here

PA1 TIM2 CH2 as output 1
PA2 TIM2 CH3 as output 2
PA2 TIM2 CH4 as output 2
The firmware library we want to use is the path of
\STM32 firmware library v3.5\STM32F10x_StdPeriph_Lib_V3.5.0\Project\STM32F10x_StdPeriph_Examples\TIM\PWM_Input\main.c
Then we found this string of codes
[easy to find because pwm input is written on the name]

Some knowledge reserves for input capture.
First, the two register configurations used for input capture

		TIM_GetCapture1(TIM2);
		得到高电平 也就是上升沿触发的次数
	    TIM_GetCapture2(TIM2);
	    得到低电平 也就是下升沿触发的次数

Then the period is the frequency of the main frequency divided by the number of triggers on the rising edge (note the type conversion in the middle)

   采集频率  =    (float)(72000/TIM_GetCapture1(TIM2)));

The duty cycle is the number of times the high level is divided by the low level (attention to the type conversion in the middle)
Channerl_2," Channerl(2):%.3fKHZ ",(float)(72000/DutyCycle_2)

 占空比=	(float)(TIM_GetCapture1(TIM2);*100/TIM_GetCapture2(TIM2);));
 /* TIM3 configuration: PWM Input mode ------------------------
     The external signal is connected to TIM3 CH2 pin (PA.01), 
     The Rising edge is used as active edge,
     The TIM3 CCR2 is used to compute the frequency value 
     The TIM3 CCR1 is used to compute the duty cycle 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_PWMIConfig(TIM3, &TIM_ICInitStructure);

  /* Select the TIM3 Input Trigger: TI2FP2 */
  TIM_SelectInputTrigger(TIM3, TIM_TS_TI2FP2);

  /* Select the slave Mode: Reset Mode */
  TIM_SelectSlaveMode(TIM3, TIM_SlaveMode_Reset);

  /* Enable the Master/Slave Mode */
  TIM_SelectMasterSlaveMode(TIM3, TIM_MasterSlaveMode_Enable);

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

  /* Enable the CC2 Interrupt Request */
  TIM_ITConfig(TIM3, TIM_IT_CC2, ENABLE);
	

Finally, just add the structure

	TIM_ICInitTypeDef  TIM_ICInitStructure;

Next, add the clock and GPIO configuration without changing it, just copy and paste it.

  /* TIM3 channel 2 pin (PA.07) configuration */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

  GPIO_Init(GPIOA, &GPIO_InitStructure);
  /* TIM3 clock enable */
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);

  /* GPIOA clock enable */
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

Then this main.c has been copied,
go out and turn right to copy the interrupt handler of
tim3 of the interrupt handler of it.c

void TIM3_IRQHandler(void)
{
    
    
  /* Clear TIM3 Capture compare interrupt pending bit */
  TIM_ClearITPendingBit(TIM3, TIM_IT_CC2);

  /* Get the Input Capture value */
  IC2Value = TIM_GetCapture2(TIM3);

  if (IC2Value != 0)
  {
    
    
    /* Duty cycle computation */
    DutyCycle = (TIM_GetCapture1(TIM3) * 100) / IC2Value;

    /* Frequency computation */
    Frequency = SystemCoreClock / IC2Value;
  }
  else
  {
    
    
    DutyCycle = 0;
    Frequency = 0;
  }
}

Finally, add the variables to him and it’s ok

__IO uint16_t IC2Value = 0;
__IO uint16_t DutyCycle = 0;
__IO uint32_t Frequency = 0;

So even if the PWM input here is configured, it
can be seen that there is no difficulty above.
Here are two important parameters, one is the duty cycle and the other is the frequency.

DutyCycle = 0;
Frequency = 0;

These two will help us get the input value


2020-10 -3 Amendment
Recently, when doing the "Dual Channel Square Wave Frequency Detection and Frequency Multiplication Output" design task book, the
timer can be used as two inputs, and
the channel initialization function needs to be changed.


  TIM_PWMIConfig(TIM3, &TIM_ICInitStructure);

Change to

  TIM_ICInit(TIM2, &TIM_ICInitStructure); //CH3  

For other GPIO IC2 IRQ, just add one more channel.
Below is the code for the dual-channel configuration (to achieve 1 timer and two channels input capture)

#include "mypwm.h"
extern  __IO uint16_t IC2Value ;
extern __IO uint16_t IC3Value ;
extern __IO uint16_t DutyCycle_CH2 ;
extern __IO uint32_t Frequency_CH2 ;
extern __IO uint16_t DutyCycle_CH3 ;
extern __IO uint32_t Frequency_CH3 ;

extern uint16_t CCR1_Val ;
extern uint16_t CCR2_Val ;
extern uint16_t PrescalerValue;
void TIM3_PWM_Output(void)  // PA6 TIM3 CH1 PA7 TIM3 CH2  
{
    
    
  /*!< At this stage the microcontroller clock setting is already configured, 
       this is done through SystemInit() function which is called from startup
       file (startup_stm32f10x_xx.s) before to branch to application main.
       To reconfigure the default setting of SystemInit() function, refer to
       system_stm32f10x.c file
     */ 
 GPIO_InitTypeDef GPIO_InitStructure;	
   TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
    TIM_OCInitTypeDef  TIM_OCInitStructure;    
  /* TIM3 clock enable */
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);

  /* GPIOA and GPIOB clock enable */
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

  GPIO_Init(GPIOA, &GPIO_InitStructure);


  /* -----------------------------------------------------------------------
    TIM3 Configuration: generate 4 PWM signals with 4 different duty cycles:
    The TIM3CLK frequency is set to SystemCoreClock (Hz), to get TIM3 counter
    clock at 24 MHz the Prescaler is computed as following:
     - Prescaler = (TIM3CLK / TIM3 counter clock) - 1
    SystemCoreClock is set to 72 MHz for Low-density, Medium-density, High-density
    and Connectivity line devices and to 24 MHz for Low-Density Value line and
    Medium-Density Value line devices

    The TIM3 is running at 36 KHz: TIM3 Frequency = TIM3 counter clock/(ARR + 1)
                                                  = 24 MHz / 666 = 36 KHz
    TIM3 Channel1 duty cycle = (TIM3_CCR1/ TIM3_ARR)* 100 = 50%
    TIM3 Channel2 duty cycle = (TIM3_CCR2/ TIM3_ARR)* 100 = 37.5%
    TIM3 Channel3 duty cycle = (TIM3_CCR3/ TIM3_ARR)* 100 = 25%
    TIM3 Channel4 duty cycle = (TIM3_CCR4/ TIM3_ARR)* 100 = 12.5%
  ----------------------------------------------------------------------- */
  /* Compute the prescaler value */
  PrescalerValue = (uint16_t) (SystemCoreClock / 24000000) - 1;
  /* Time base configuration */
  TIM_TimeBaseStructure.TIM_Period = 665;
  TIM_TimeBaseStructure.TIM_Prescaler = PrescalerValue;
  TIM_TimeBaseStructure.TIM_ClockDivision = 0;
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;

  TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);

  /* PWM1 Mode configuration: Channel1 */
  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_OC1Init(TIM3, &TIM_OCInitStructure);

  TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable);

  /* PWM1 Mode configuration: Channel2 */
  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
  TIM_OCInitStructure.TIM_Pulse = CCR2_Val;

  TIM_OC2Init(TIM3, &TIM_OCInitStructure);

  TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable);

  /* PWM1 Mode configuration: Channel3 */
  TIM_ARRPreloadConfig(TIM3, ENABLE);

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

void TIM2_PWM_Input(void)  // PA1 TIM2 CH2  pwmÊäÈë //PA2 TIM2 CH3  pwmÊäÈë
{
    
    
		TIM_ICInitTypeDef  TIM_ICInitStructure;
	  GPIO_InitTypeDef GPIO_InitStructure;
	  NVIC_InitTypeDef NVIC_InitStructure;
	
	  /* TIM2 clock enable */
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);

  /* GPIOA clock enable */
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
  /* TIM2 channel 2 pin (PA.07) configuration */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

  GPIO_Init(GPIOA, &GPIO_InitStructure);
	
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

  GPIO_Init(GPIOA, &GPIO_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 configuration: PWM Input mode ------------------------
     The external signal is connected to TIM2 CH2 pin (PA.01), 
     The Rising edge is used as active edge,
     The TIM2 CCR2 is used to compute the frequency value 
     The TIM2 CCR1 is used to compute the duty cycle 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(TIM2, &TIM_ICInitStructure);  //CH2
	
	  TIM_ICInitStructure.TIM_Channel = TIM_Channel_3;
  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); //CH3  

  /* Select the TIM2 Input Trigger: TI2FP2 */
  TIM_SelectInputTrigger(TIM2, TIM_TS_TI2FP2);

  /* Select the slave Mode: Reset Mode */
  TIM_SelectSlaveMode(TIM2, TIM_SlaveMode_Reset);

  /* Enable the Master/Slave Mode */
  TIM_SelectMasterSlaveMode(TIM2, TIM_MasterSlaveMode_Enable);

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

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

void TIM2_IRQHandler(void)
{
    
    
	
	

	
					TIM_ClearITPendingBit(TIM2, TIM_IT_CC2);
					IC2Value = TIM_GetCapture2(TIM2);
					if (IC2Value != 0)
			{
    
    
				/* Duty cycle computation */
				DutyCycle_CH2 = (TIM_GetCapture2(TIM2) * 100) / IC2Value;

				/* Frequency computation */
				Frequency_CH2 = SystemCoreClock / IC2Value;
			}
			else
			{
    
    
				DutyCycle_CH2 = 0;
				Frequency_CH2 = 0;
			}
	

	

		
				TIM_ClearITPendingBit(TIM2, TIM_IT_CC3);
				/* Get the Input Capture value */

				IC3Value = TIM_GetCapture3(TIM2);

				
					if (IC3Value != 0)
				{
    
    
					/* Duty cycle computation */
					DutyCycle_CH3 = (TIM_GetCapture3(TIM2) * 100) / IC3Value;

					/* Frequency computation */
					Frequency_CH3 = SystemCoreClock / IC3Value;
				}
				else
				{
    
    
					DutyCycle_CH3 = 0;
					Frequency_CH3 = 0;
				}
    
}


Guess you like

Origin blog.csdn.net/m0_46179894/article/details/108905077