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.