Timer 1 outputs PWM code, plus explanation

Posted by newbreed65 on Mon, 13 Sep 2021 00:46:05 +0200

Explain the function of PWM initialization of 32 in depth

I'll post the code directly first

void TIM1_PWM_Init(u16 arr, u16 psc)
{
  GPIO_InitTypeDef GPIO_InitStructure;
	TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
	TIM_OCInitTypeDef  TIM_OCInitStructure;
	
 
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1 | RCC_APB2Periph_GPIOA, ENABLE);	//Enable timer 1 clock
	
 
   //Set this pin as the multiplexing output function to output the PWM pulse waveform of TIM2 CH1 	 GPIOA.0
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8| GPIO_Pin_11; //TIM_CH1  TIM_CH2
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  //Push pull output
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);//Initialize GPIO
 
   //Initialize TIM2
	TIM_TimeBaseStructure.TIM_Period = arr; //Sets the value of the auto reload register cycle of the load activity at the next update event
	TIM_TimeBaseStructure.TIM_Prescaler =psc; //Sets the prescaled value used as the divisor of TIMx clock frequency 
	TIM_TimeBaseStructure.TIM_ClockDivision = 0; //Set clock division: TDTS = Tck_tim
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM up count mode
	TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure); //According to Tim_ The parameter specified in timebaseinitstruct initializes the time base unit of TIMx
	
	//Initialize TIM Channel 1-4 PWM mode	 
	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //Select timer mode: TIM pulse width modulation mode 1
 	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //Compare output enable
	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //Output polarity: TIM output has high polarity
	TIM_OC1Init(TIM1, &TIM_OCInitStructure);  //Initialize the peripheral TIM1 OC1 according to the parameters specified by T
	TIM_OC4Init(TIM1, &TIM_OCInitStructure);  //Initialize the peripheral TIM1 OC4 according to the parameters specified by T
 
	TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable);  //Enable TIM1_ Preload register on ch1
	TIM_OC4PreloadConfig(TIM1, TIM_OCPreload_Enable);  //Enable TIM1_ Preload register on CH4
 
	TIM_Cmd(TIM1, ENABLE);  //Enable TIM1
	TIM_ARRPreloadConfig(TIM1, ENABLE); //Enable TIMx preload register on ARR
	TIM_CtrlPWMOutputs(TIM1,ENABLE);        //MOE main output enable, advanced timer must be enabled

}

The first is the structure. There is no need to talk about this part

    GPIO_InitTypeDef GPIO_InitStructure;
	TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
	TIM_OCInitTypeDef  TIM_OCInitStructure;

Then turn on the clock of timer 1 and the clock of pin A

RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1 | RCC_APB2Periph_GPIOA, ENABLE);	//Enable timer 1 clock

Then the initialization pin

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8| GPIO_Pin_11; //TIM_CH1  TIM_CH2
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  //Push pull output
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);//Initialize GPIO

The next step is the initialization of the timer

TIM_TimeBaseStructure.TIM_Period = arr; 

Here is to set the length of a cycle of the timer. After a cycle ends, it will enter the timer with a new automatic reload value
And this

TIM_TimeBaseStructure.TIM_Prescaler =psc; //Sets the prescaled value used as the divisor of TIMx clock frequency 

This and the above arr will determine the frequency of the output pwm
The calculation formula is 72 MHz / (arr * PSC), and the value obtained is the frequency of pwm
Why 72MHZ? This is the main frequency of the chip output
Then there is

TIM_TimeBaseStructure.TIM_ClockDivision = 0; //Set clock division: TDTS = Tck_tim

Here we don't use clock division, so we set it to 0
Next, there are two counting methods

TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM up count mode

This is more fun. I use the up counting mode above
That is, the timer will count from 0 to arr
Suppose I set the arr to 7199
The counter will count until 7199, and the next cycle will proceed
If it's down mode
It's the opposite. It's all the way down from the arr
And this

TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //Output polarity: TIM output has high polarity

This may be troublesome to understand. The comment here also says that the output polarity is high. Later, there is a function to set the output duty cycle
that is

TIM_SetCompare1(TIM1, 3000);

This, this can set the duty cycle, which means that in the up counter mode, the output level during counting from 0 to 3000 is high level. For example, we set the arr to 10000, and the duty control ratio here is 3000, that is, the high level accounts for 30%.
What's the use of this? Generally, we often use the steering gear. Its working principle is that under the pwm of 50HZ frequency, the time of a cycle is 20ms. If its high level accounts for 1.5ms, it will rotate 90 degrees. I won't talk about other angles. If it rotates 90 degrees, what should be the duty cycle of this setting? Let's assume that arr is 199, psc is 7199, and the duty cycle we set is 15
Then select the output mode as the output mode. If the output mode is low, the duty cycle we set is 185. Because it needs arr to be reduced all the time, its duty cycle is set to 185
Next is

TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;

This explanation is this article Difference between PWM1 and PWM2
And then

    TIM_OC1Init(TIM1, &TIM_OCInitStructure);  //Initialize the peripheral TIM1 OC1 according to the parameters specified by T
	TIM_OC4Init(TIM1, &TIM_OCInitStructure);  //Initialize the peripheral TIM1 OC4 according to the parameters specified by T

Here is to set different channels

    TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable);  //Enable TIM1_ Preload register on ch1
	TIM_OC4PreloadConfig(TIM1, TIM_OCPreload_Enable);  //Enable TIM1_ Preload register on CH4

The same is true for this paragraph. If you configure multiple channels, don't leave it here

Finally

    TIM_Cmd(TIM1, ENABLE);  //Enable TIM1
	TIM_ARRPreloadConfig(TIM1, ENABLE); //Enable TIMx preload register on ARR
	TIM_CtrlPWMOutputs(TIM1,ENABLE);        //MOE main output enable, advanced timer must be enabled

The last line is special, because timer 1 is an advanced timer, which must be turned on, and other ordinary timers do not·
Finally, what I said is not very good. If there is any mistake, please point it out.

Topics: stm32