I. the PWM output pin of stm32 is the reuse function of the I/O port.
Ii. T2 ~ T5 these 4 Universal timers can output 4-way PWM--CH1 ~ .
3. We will use tim3's PWM output as an example to explain the text (other similar ), finally, we will provide the C code output by the two PWM methods of tim3 and CH2 (the test has been successful on stm32f103rbt6, so you can use it with confidence !).
4. The formula for calculating the PWM frequency and duty cycle is given.
The procedure is as follows:
1. Enable tim3 clock
RCC-> apb1enr | = 1 <1;
2. Configure the reuse output function of the corresponding pins (6)
Gpioa-> CRL & = 0xf0ffffff; // clear 0 for PA66
Gpioa-> CRL | = 0x0b000000; // reuse function output (push and pull 50 MHz output)
Gpioa-> ODR | = 1 <6; // pull-up on the PA66
3. Set the counter auto-reinstallation value and whether to calculate the frequency.
Tim3-> arr = arr; // sets the counter auto-reinstallation value (determines the PWM frequency)
Tim3-> PSC = PSC; // pre-divider, 0 is not divided
4. Set the PWM mode (there are two modes, the difference is that the output level polarity is opposite). Select one as needed.
Note: timx_ccmr1 determines whether to renew ~ CH2 path, timx_ccmr2 decide CH3 ~ .
// Tim3-> ccmr1 | = 6 <4; // pwm1 Mode
Tim3-> ccmr1 | = 7 <4; // pwm2 Mode
Tim3-> ccmr1 | = 1 <3; // enables the executor pre-load
5. Output enabling settings
Tim3-> CCER | = 1 <0; // input/capture 1 Output
6. automatic re-loading pre-loading allowable bit (Arpe) and Timer
Enable
Tim3-> CR1 = 0x0080; // Arpe enabled (this sentence is not configured as well)
Tim3-> CR1 | = 0x01; // enable timer 3
The following is the PWM output code of tim3_ch1 and tim3_ch2:
Void pwm_init_tim3_ch1 (2010arr, 2010psc)
{
// 1. Enable tim3 clock
RCC-> apb1enr | = 1 <1; // enables tim3 clock
// 2. Configure the reuse output function of the corresponding pins (6)
Gpioa-> CRL & = 0xf0ffffff; // clear 0 for PA66
Gpioa-> CRL | = 0x0b000000; // reuse function output (push and pull 50 MHz output)
Gpioa-> ODR | = 1 <6; // pull-up on the PA66
// 3. Set the counter auto-reinstallation value and whether to calculate the frequency.
Tim3-> arr = arr; // sets the counter auto-reinstallation value (determines the PWM frequency)
Tim3-> PSC = PSC; // The pre-divider 0 is not divided
// 4. Set the PWM mode
Tim3-> ccmr1 | = 7 <4; // pwm2 Mode
Tim3-> ccmr1 | = 1 <3; // enables the executor pre-load
// 5. Output enabling settings
Tim3-> CCER | = 1 <0; // input/capture 1 Output
// 6. Auto-Reload pre-load allowable bit (Arpe) and Timer
Enable
Tim3-> CR1 = 0x0080; // Arpe enabling
Tim3-> CR1 | = 0x01; // enable timer 3
}
Void pwm_init_tim3_ch2 (2010arr, 2010psc)
{
RCC-> apb1enr | = 1 <1; // enables tim3 clock
Gpioa-> CRL & = 0x0fffffff; // pa7 clear 0
Gpioa-> CRL | = 0xb0000000; // reuse function output (push and pull 50 MHz output)
Gpioa-> ODR | = 1 <7; // pull up pa7
Tim3-> arr = arr; // sets the counter auto-reinstallation value (determines the PWM frequency)
Tim3-> PSC = PSC; // The pre-divider does not divide the frequency
Tim3-> ccmr1 | = 7 <12; // CH2 pwm2 Mode
Tim3-> ccmr1 | = 1 <11; // CH2 pre-load enabling
Tim3-> CCER | = 1 <4; // input/capture 2 output
Tim3-> CR1 = 0x0080; // Arpe enabling
Tim3-> CR1 | = 0x01; // enable timer 3
}
Frequency:
// Fpwm = 72 m/(ARR + 1) * (PSC + 1) (unit: Hz)
Duty cycle:
// Duty Circle = tim3-> CCR1/ARR (Unit: %)
Note: The PWM output frequency of one of the four timer channels in this method is the same, but the duty cycle can be different!