You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多
文档控制台
免费开始使用

求STM32定时器PWM输出的预分频器、周期及通道脉冲值计算公式

Hey folks, let's walk through exactly how to calculate the prescaler (PSC), counter period (ARR), and channel pulse values (CCRx) for STM32 timers when you have your APB input clock, desired PWM frequency, and each channel's duty cycle. I'll break this down with clear formulas and a practical example to make it stick.

First, Understand the Timer Clock Source

Before diving into calculations, remember STM32 timers follow a specific clock rule:

  • If your APB bus prescaler is set to 1, the timer clock (TIM_CLK) equals the APB input clock.
  • If the APB prescaler is greater than 1, the timer clock is twice the APB input clock.

We'll use TIM_CLK as the base clock for all our math below.

1. Calculate Prescaler (PSC) and Counter Period (ARR)

The core formula linking PWM frequency to timer parameters is:

PWM_Freq = TIM_CLK / [(PSC + 1) × (ARR + 1)]

Rearranged to solve for the product of our timer registers:

(PSC + 1) × (ARR + 1) = TIM_CLK / PWM_Freq

How to Pick Valid PSC and ARR Values:

  • Start by choosing a value for ARR + 1 (the total counter count). For better duty cycle resolution, aim for the largest possible ARR that keeps PSC within the timer's range (0 to 65535 for 16-bit timers; up to 4,294,967,295 for 32-bit timers like TIM2/TIM5).
  • Once you've fixed ARR + 1, calculate PSC with:
    PSC = (TIM_CLK / (PWM_Freq × (ARR + 1))) - 1
    
    Important: PSC must be an integer. If your calculation gives a non-integer, adjust ARR + 1 slightly and recalculate to minimize frequency error.
2. Calculate Channel Pulse Values (CCRx)

The pulse value sets the duty cycle for each PWM channel. The formula depends on your chosen PWM mode—we'll use the most common one: up-counting PWM Mode 1 (output is high when the counter CNT is less than CCRx).

For this mode, duty cycle = CCRx / (ARR + 1), so rearranged:

CCRx = round((ARR + 1) × Duty_Cycle)
  • Duty_Cycle is a decimal between 0 and 1 (e.g., 30% = 0.3, 75% = 0.75)
  • Use round() to get an integer value since CCRx must be an integer.

For PWM Mode 2 (Output High When CNT > CCRx):

If you're using Mode 2, the duty cycle becomes (ARR + 1 - CCRx) / (ARR + 1), so adjust the formula to:

CCRx = round((ARR + 1) × (1 - Duty_Cycle))
Practical Example

Let's put this into action with real numbers:

  • APB Input Clock = 36MHz, APB Prescaler = 2 → TIM_CLK = 36MHz × 2 = 72MHz
  • Desired PWM Frequency = 2kHz
  • Channel 1 Duty Cycle = 30%, Channel 2 Duty Cycle = 75%

Step 1: Find (PSC+1) × (ARR+1)

(PSC+1) × (ARR+1) = 72e6 / 2e3 = 36000

Choose ARR + 1 = 400 (so ARR = 399). Then:

PSC + 1 = 36000 / 400 = 90 → PSC = 89

Step 2: Calculate CCRx Values

  • Channel 1: CCR1 = 400 × 0.3 = 120
  • Channel 2: CCR2 = 400 × 0.75 = 300

This setup gives us exactly 2kHz PWM, with 30% and 75% duty cycles for the two channels.

Quick Notes to Avoid Headaches
  • Always double-check that PSC and ARR are within your timer's hardware limits (16-bit vs 32-bit).
  • If you need ultra-high resolution, prioritize a larger ARR over a smaller one (since it gives more fine-grained control over duty cycle).
  • For center-aligned PWM modes, the calculations change slightly—feel free to ask for clarification if you need that!

内容的提问来源于stack exchange,提问作者TonyP

火山引擎 最新活动