PWM signal statistics frequency and duty cycle

To do a project recently, you need to count the frequency and duty cycle of the external PWM signal.

Using the STM32F207 movie

Looking at the datasheet, one of the several major functions of the timer is the comparison of the capture of the PWM signal. Note The timer can generate PWM signals and can also capture external PWM signals.

Simulate it yourself, the output of the D0 foot function PWM signal, adjust the high and low output time with the timer 3, even if the duty cycle is adjustable PWM signal.

The CH2 of the timer 2 is used as the input pin of the PWM signal, that is, the GPIOA1 pin, and D0 is connected to the A1 pin.

PWM signal statistics frequency and duty cycle

First configure it

//GPIO configuration

RCC_AHBxPeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE); //A port

RCC_AHBxPeriphClockCmd(RCC_AHB1Periph_GPIOD,ENABLE);

RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);

GPIO_PinAFConfig(GPIOA, GPIO_PinSource1, GPIO_AF_TIM2);//A0 is multiplexed as timer 2

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; //Configure to Reuse Foot

GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;

GPIO_InitStructure.GPIO_Speed ​​= GPIO_Speed_100MHz;

GPIO_Init(GPIOA, &GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;

GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;

GPIO_InitStructure.GPIO_Speed ​​= GPIO_Speed_100MHz;

GPIO_Init(GPIOD, & GPIO_InitStructure);

// Two-way timer configuration, this timer configuration still has mystery in it, etc.

Void TIM3_ConfiguraTIon(void)

{

TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);

/* ------------------------------------------------ ---------------

PCLK1=120/4=30MHz

TIM2 CLK = 30MHz * 2 = 60MHz, Prescaler = 300, TIM3 counter clock = 50, cycle time is 4K, timer time is 0.25mS

-------------------------------------------------- ------------- */

/* Time base configuration */

TIM_TimeBaseStructure.TIM_Period = 50;

TIM_TimeBaseStructure.TIM_Prescaler = (300-1);

TIM_TimeBaseStructure.TIM_ClockDivision = 0;

TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;

TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);

/*------------------------------------------------ ----------------

TIM IT enable Enables or disables the specified TIM interrupt

TIM3: TIM interrupt source

TIM_IT_Update | TIM_IT_Trigger: TIM triggers an interrupt source

-------------------------------------------------- --------------*/

TIM_ITConfig(TIM3, TIM_IT_Update | TIM_IT_Trigger, ENABLE);

/* TIM3 enable counter Enable TIMx Peripheral */

TIM_Cmd(TIM3, ENABLE);

}

/ / The standard library comes with an example of the number of functions F2, we can study under their own

Void TIM2_Configuration(void)

{

TIM_ICInitTypeDef TIM_ICInitStructure;

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);

/* Time base configuration */

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(TIM2, &TIM_ICInitStructure);

/* 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 */

/* Enable the CC2 Interrupt Request */

TIM_ITConfig(TIM2, TIM_IT_CC2, ENABLE);

TIM_Cmd(TIM2, ENABLE);

}

/ / Interrupt processing, see here with the global variable tim_cnt take a natural number, you can adjust the duty cycle, for example, tim_cnt accumulated multiples of 4 before pulling up, the rest are all low, that high-level accounted for The air ratio is 1/4=25%

Void TIM3_IRQHandler(void)

{

//int i;

If (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET) // Check if the specified TIM interrupt occurs or not: TIM interrupt source

{

If((tim_cnt%4) == 0)

GPIO_SetBits(GPIOD, GPIO_Pin_0);

Else

GPIO_ResetBits(GPIOD, GPIO_Pin_0);

Tim_cnt++;

TIM_ClearITPendingBit(TIM3, TIM_IT_Update);

}

}

//This timer is to calculate the frequency and duty cycle of the PWM signal

Void TIM2_IRQHandler(void)

{

RCC_ClocksTypeDef RCC_Clocks;

RCC_GetClocksFreq(&RCC_Clocks);

/* Clear TIM2 Capture compare interrupt pending bit */

TIM_ClearITPendingBit(TIM2, TIM_IT_CC2);

/* Get the Input Capture value */

IC2Value = TIM_GetCapture2(TIM2);

//printf("IC2Value:%d!!!",IC2Value);

If (IC2Value != 0)

{

/* Duty cycle computation */

IC1Value = TIM_GetCapture1(TIM2);

DutyCycle = (IC1Value * 100) / IC2Value;

/* Frequency computation */

Frequency = (RCC_Clocks.HCLK_Frequency) / 2 / IC2Value;

//Frequency = 30000000 / IC2Value;

//printf("clk:%d!!!",RCC_Clocks.HCLK_Frequency);

}

Else

{

DutyCycle = 0;

Frequency = 0;

}

}

The PWM input capture mode is a special case of the input capture mode. It is understood as follows

1. Each timer has four input capture channels IC1, IC2, IC3, and IC4. And IC1 IC2 group, IC3 IC4 group. And you can set the correspondence between pins and registers.

2. Two ICx signals are mapped on the same TIx input.

3. The two ICx signals are valid on opposite polarity edges, respectively.

4. One of the two edge signals is selected as the trigger signal, and the slave mode controller is set to the reset mode.

5. When the trigger signal comes, set the capture register of the trigger input signal to capture “a PWM period (ie, two consecutive rising or falling edges)”, which is equal to the number of TIM clock cycles (ie, the capture register). Number of counts for TIM captured in n).

6. The same capture channel captures the number of counts m of the trigger signal and the next opposite-polarity edge signal (ie, high-level period or low-level period).

7. This will calculate the PWM clock cycle and duty cycle

Frequency=f(TIM clock frequency)/n.

Duty cycle=(high number of counts/n),

If m is the number of high counts, then duty cycle=m/n

If m is the number of low counts, then duty cycle=(nm)/n

Note: Because the counter is 16 bits, a maximum of 65,535 cycles is counted, so the minimum frequency measured is TIM clock frequency/65535.

According to the calculator is 65535, it can be imagined, PWM frequency range is roughly between 1k ~ 1M, so the timer 3 cycle time to be adjusted according to the duty cycle of D0, to ensure the entire cycle time in the 1K and 1M between. If you want to adjust the duty cycle to 10, then the TIM3 timing can only be less than 0.1mS, of course, this method is a bit silly, you can not do this

The printed result is DutyCycle:24, Frequency:980

Calculate according to the above settings is correct, because each PWM signal 4 times TIM3 is 1mS, high-level accounted for a quarter or 25%, a little error

Wireless Earbuds

We've been around for over 16+ years. We make sure our sound is The Best Sound.


Our products include TWS earbuds, Bluetooth Earphone, Headphones Noise Cancelling, Best Wireless Earbuds, Bluetooth Mask, Headphones For Sleeping, Headphones in Headband, Bluetooth Beanie Hat, bluetooth for motorcycle helmet, etc

Manufacturing high-quality products for customers according to international standards, such as CE ROHS FCC REACH UL SGS BQB etc.


We help 200+ customers create custom Bluetooth headphones, earbuds, earphones, etc audio products design for various industries.

wholesale earbuds, earbuds in bulk, earbuds custom, true wireless earbuds

TOPNOTCH INTERNATIONAL GROUP LIMITED , https://www.itopnoobluetoothes.com