IDC connectors,ZOOKE IDC connectors,IDC connectors series Zooke Connectors Co., Ltd. , https://www.zooke.com
Pmm output and frequency calculation method of stm32
Here's a rewritten and improved version of the original content in English, with added explanations to make it more natural and comprehensive:
---
First, the PWM output pin on the STM32 is a multiplexed function of the selected GPIO pin.
Second, the general-purpose timers T2 to T5 can each generate four PWM channels (CH1 to CH4).
Third, we'll use TIM3's CH1 as an example to explain how PWM works. The same method applies to other channels. Finally, I will provide tested C code for generating PWM signals on TIM3_CH1 and TIM3_CH2, which has been successfully verified on the STM32F103RBT6 microcontroller. You can confidently use this code in your own projects.
Fourth, I will also explain the formulas for calculating PWM frequency and duty cycle.
Let’s go through the steps:
1. **Enable the TIM3 Clock**
To start using the timer, you need to enable its clock. This is done by setting the appropriate bit in the RCC_APB1ENR register.
```c
RCC->APB1ENR |= 1 << 1; // Enable TIM3 clock
```
2. **Configure the Multiplexed Output Function of the Pin (PA6 for CH1)**
For PWM output, the corresponding GPIO pin must be configured as a multiplexed output. In this case, we're using PA6 for TIM3_CH1.
```c
GPIOA->CRL &= 0xF0FFFFFF; // Clear the configuration bits for PA6
GPIOA->CRL |= 0x0B000000; // Set PA6 as alternate function push-pull output (50 MHz)
GPIOA->ODR |= 1 << 6; // Set PA6 high
```
3. **Set the Counter Auto-Reload Value and Prescaler**
The ARR (Auto-Reload Register) determines the PWM frequency, while the PSC (Prescaler) controls the division of the input clock.
```c
TIM3->ARR = arr; // Set the auto-reload value (determines frequency)
TIM3->PSC = psc; // Set the prescaler (0 means no division)
```
4. **Set the PWM Mode**
There are two main PWM modes: mode 1 and mode 2. These differ in the polarity of the output signal. Choose the one that suits your application.
- `TIM3->CCMR1 |= 7` – Set PWM mode 1 (active high)
- `TIM3->CCMR1 |= 1` – Set PWM mode 2 (active low)
Note: `TIMX_CCMR1` controls CH1 and CH2, while `TIMX_CCMR2` controls CH3 and CH4.
5. **Enable the Output**
After configuring the mode, you need to enable the output for the specific channel.
```c
TIM3->CCER |= 1; // Enable the output for CH1
```
6. **Enable Auto-Reload Preload and Start the Timer**
Enabling the ARPE (Auto-Reload Preload Enable) ensures that the new values take effect at the next update event. Then, start the timer.
```c
TIM3->CR1 |= 0x0080; // Enable ARPE
TIM3->CR1 |= 0x01; // Start the timer
```
### PWM Initialization Functions
Here are the functions to initialize PWM on TIM3_CH1 and TIM3_CH2:
```c
void PWM_Init_TIM3_CH1(u16 arr, u16 psc) {
// 1. Enable TIM3 clock
RCC->APB1ENR |= 1 << 1;
// 2. Configure PA6 as alternate function output
GPIOA->CRL &= 0xF0FFFFFF;
GPIOA->CRL |= 0x0B000000;
GPIOA->ODR |= 1 << 6;
// 3. Set auto-reload and prescaler
TIM3->ARR = arr;
TIM3->PSC = psc;
// 4. Set PWM mode
TIM3->CCMR1 |= 7;
TIM3->CCMR1 |= 1;
// 5. Enable output
TIM3->CCER |= 1;
// 6. Enable ARPE and start the timer
TIM3->CR1 |= 0x0080;
TIM3->CR1 |= 0x01;
}
void PWM_Init_TIM3_CH2(u16 arr, u16 psc) {
// 1. Enable TIM3 clock
RCC->APB1ENR |= 1 << 1;
// 2. Configure PA7 as alternate function output
GPIOA->CRL &= 0x0FFFFFFF;
GPIOA->CRL |= 0xB0000000;
GPIOA->ODR |= 1 << 7;
// 3. Set auto-reload and prescaler
TIM3->ARR = arr;
TIM3->PSC = psc;
// 4. Set PWM mode
TIM3->CCMR1 |= 7;
TIM3->CCMR1 |= 1;
// 5. Enable output
TIM3->CCER |= 1 << 4; // CH2 enable
// 6. Enable ARPE and start the timer
TIM3->CR1 |= 0x0080;
TIM3->CR1 |= 0x01;
}
```
### PWM Frequency and Duty Cycle Calculation
- **Frequency**:
`Fpwm = 72M / ((arr + 1) * (psc + 1))` (in Hz)
- **Duty Cycle**:
`Duty Cycle = TIM3->CCR1 / arr * 100%`
Note: All four channels of the same timer share the same frequency, but their duty cycles can be set independently.