Note: qq:468001647
PWM is widely used in control, from single motor control to servo control to manipulator control. However, it would be very troublesome to call all the way PWM directly in the project. Engineers should pay more attention to the research of algorithm and debugging of products, rather than to the basic rated control of single-chip microcontroller. Moreover, if the official library provided by registers or ST is used directly, the project will become very messy, No. It is conducive to the later development. Here, I have established an engineering library, which can support 16-way PWM output of STM32F1 series.
The following is a detailed explanation of the project.
First, let's look at the output of a section of PWM. Take PWM1 as an example. Before that, I'll show you the distribution of PWM pins, as follows:
Let's take channel 1 of PWM1 as an example.
No more nonsense, code it:

RCC - > APB2ENR |= 1
It is clear that to enable TIM1, the RCC_APB2ENR register must be located at 11 position 1, so that it can be enabled!
Okay, we activated TIM1 and then we have to enable it to output pins. This is PA8. So I won't introduce it much from the second line to the third line. It's worth noting that the pins here must be set as multiplexing function output.

TIM1 - > ARR = arr_init; // Set counter auto-reload value
TIM1 - > PSC = psc_init; / / Predivider settings
Comparing these two sentences is the most important part of PWM. It took me a lot of effort to understand this when I first learned it. Let me also briefly explain the principle here.
ARR refers to the automatic reload value and PSC refers to the pre-frequency value.
We know that F103 is basically the main frequency of 72MHZ, so the figure above is a period of waveform in a cycle. We divide a unit time into PSC segments, just like the sharp waves in the picture above (a sharp wave is a paragraph, a unit time has a PSC such a period). ARR is that each paragraph will reach a peak, the peak is ARR;
The two values are TIM1 - > ARR = arr_init; TIM1 - > PSC = psc_init;
Of course, here's a formula that needs special attention: frequency = 72000 000 000/((ARR+1) (PSC+1))*

Then we will talk about two modes of PWM: PWM1 and PWM2.
PWM1 mode: The CCRx on the graph is a value that you need to set (after that). In the same paragraph, it is high before counting CCRx, but once counting CCRx, it will become low. But when this paragraph ends, it will go to the next paragraph, and it will become high until the next one. The emergence of CCRx is repeated.
PWM2 mode: Contrary to PWM1 mode, in the same paragraph, the level before CCRx is low, and then high!
Then set the mode to a dedicated register: TIMx_CCMR1!
We can see that,
Enabling PWM1, mode written as follows: TIM1 - > CCMR1 |= 6 < 4; // PWM1 mode
Enabling PWM2, mode as follows: TIM1 - > CCMR1 |= 7 < 4; //PWM2 mode

In this way, PWM mode enabled to complete, the following is pre-loading enablement, output enablement and total enablement, in particular: only TIM1 this advanced timer needs to enable MOE, TIM1 - > BDTR |= 1 < 15;!!
Here's the complete enabling processTIM1 - > CCMR1 |= 1 < 3;//CH1 preloading enablement
TIM1 - > CCER |= 1 < 0; //OC1 output enablement
TIM1 - > BDTR |= 1 # 15; //MOE main output enablement
Here's the reference manual on the content I did not show one by one, interested can refer to, lazy words can be directly invoked!
However, it is worth mentioning that if the channel changes, the number of displacements must be changed. This reader can refer to the manual. I will give the code of other cases below.

The following is the power of ARPE, which can be directly invoked as above. Normally, the configuration will not change much.

TIM1->CR1=0x0080; //ARPE enable
TIM1->CR1|=0x01; //Enabling timer 1

Finally, the value of CCR1 is initialized (as follows, call directly, refer to above for explanation):
TIM1->CCR1 =PWM_VAL;
In this way, the PWM initialization statement is completed!!

Then if you need to change the duty cycle of PWM in main.c file, you can assign TIM1 - > CCR1 directly!!!

So, here's my programming habits:
1. I am used to PWM1
2. I normally assign PSC to 0 and ARR to 7199. Why?? This frequency F = 72,000,000/((7199+1)* (0+1)) = 10,000, i.e. 10,000 copies per minute, which is convenient and accurate!
The following is the PWM library I wrote:

So if you don't understand anything, or think there's something wrong with what I said above or in the library, you can always trust me and send me my personal qqq: 468001647.
I also very much hope that students who like single-chip technology can communicate with me and make progress together!!!