STM32 Timer Implementation and PWM Control

Timers in STM32

Timers in STM32 microcontrollers are versatile peripherals that can count input clock signals and trigger interrupts when the count reaches a predetermined value. The timer's time base unit consists of a 16-bit counter, prescaler, and auto-reload register, enabling maximum timing periods of 59.65 seconds with a 72MHz clock. Beyond basic timing functions, STM32 timers offer multiple advanced features including clock source selection, input capture, output comparison, encoder interface, and master-slave trigger modes.

STM32 timers are categorized into three types based on complexity and application scenarios: advanced timers, general-purpose timers, and basic timers.

Timer Interrupt Implementation

The counter frequency is calculated as: CK_CNT = CK_PSC / (PSC + 1)


#include "stm32f10x.h"

void Timer_Init(void)
{
    // Enable clock for TIM2
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
    
    // Configure timer to use internal clock
    TIM_InternalClockConfig(TIM2);
    
    // Timer base configuration
    TIM_TimeBaseInitTypeDef timerConfig;
    timerConfig.TIM_ClockDivision = TIM_CKD_DIV1;
    timerConfig.TIM_CounterMode = TIM_CounterMode_Up;
    timerConfig.TIM_Period = 9999;  // Auto-reload value
    timerConfig.TIM_Prescaler = 7199;  // Prescaler value
    timerConfig.TIM_RepetitionCounter = 0;
    TIM_TimeBaseInit(TIM2, &timerConfig);
    
    // Clear update flag and enable update interrupt
    TIM_ClearFlag(TIM2, TIM_FLAG_Update);
    TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
    
    // Configure NVIC
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
    
    NVIC_InitTypeDef nvicConfig;
    nvicConfig.NVIC_IRQChannel = TIM2_IRQn;
    nvicConfig.NVIC_IRQChannelCmd = ENABLE;
    nvicConfig.NVIC_IRQChannelPreemptionPriority = 2;
    nvicConfig.NVIC_IRQChannelSubPriority = 1;
    NVIC_Init(&nvicConfig);
    
    // Start timer
    TIM_Cmd(TIM2, ENABLE);
}

// Timer interrupt handler
void TIM2_IRQHandler(void)
{
    if (TIM_GetITStatus(TIM2, TIM_IT_Update) == SET)
    {
        // User code to execute in interrupt
        TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
    }
}

Output Compare for PWM Generation

Output Compare (OC) functionality allows the timer to control output levels by comparing the counter value (CNT) with the capture/compare register (CCR) value. This feature is commonly used to generate PWM (Pulse Width Modulation) signals with specific frequencies and duty cycles.

Each advanced and general-purpose timer includes four output compare channels. The first three channels of advanced timers additionally feature dead-time generation and complementary output capabilities.

PWM (Pulse Width Modulation) is a technique that uses pulse width modulation to simulate analog quantities in systems with inertia, widely used in motor speed control applications.

PWM parameters:

  • Frequency = 1 / TS
  • Duty cycle = TON / TS
  • Resolution = Step size of duty cycle changes

PWM frequency calculation: Freq = CK_PSC / (PSC + 1) / (ARR + 1)

PWM duty cycle calculation: Duty = CCR / (ARR + 1)

PWM resolution calculation: Reso = 1 / (ARR + 1)


#include "stm32f10x.h"

void PWM_Init(void)
{
    // Enable clock for TIM2 and GPIOA
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
    
    // Configure PA0 as alternate function output
    GPIO_InitTypeDef gpioConfig;
    gpioConfig.GPIO_Mode = GPIO_Mode_AF_PP;
    gpioConfig.GPIO_Pin = GPIO_Pin_0;
    gpioConfig.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &gpioConfig);
    
    // Configure timer for internal clock
    TIM_InternalClockConfig(TIM2);
    
    // Timer base configuration
    TIM_TimeBaseInitTypeDef timerConfig;
    timerConfig.TIM_ClockDivision = TIM_CKD_DIV1;
    timerConfig.TIM_CounterMode = TIM_CounterMode_Up;
    timerConfig.TIM_Period = 99;  // Auto-reload value (ARR)
    timerConfig.TIM_Prescaler = 719;  // Prescaler value (PSC)
    timerConfig.TIM_RepetitionCounter = 0;
    TIM_TimeBaseInit(TIM2, &timerConfig);
    
    // Output compare configuration for PWM mode 1
    TIM_OCInitTypeDef ocConfig;
    TIM_OCStructInit(&ocConfig);
    ocConfig.TIM_OCMode = TIM_OCMode_PWM1;
    ocConfig.TIM_OCPolarity = TIM_OCPolarity_High;
    ocConfig.TIM_OutputState = TIM_OutputState_Enable;
    ocConfig.TIM_Pulse = 0;  // Capture/compare value (CCR)
    TIM_OC1Init(TIM2, &ocConfig);
    
    // Enable timer
    TIM_Cmd(TIM2, ENABLE);
}

// Function to update PWM duty cycle
void PWM_SetDutyCycle(uint16_t compareValue)
{
    TIM_SetCompare1(TIM2, compareValue);
}

Servo Motor Control

A servo motor is a device that controls output angles based on the duty cycle of an input PWM signal. The required input PWM signal has a period of 20ms, with the high-level duration ranging from 0.5ms to 2.5ms.

For servo motor control, a 20ms period base pulse is typically needed. The high-level portion of this pulse (0.5ms-2.5ms) serves as the angle control signal. For a 180-degree servo, the relationship between pulse width and angle is as follows:

  • 0.5ms pulse width = 0 degrees
  • 1.0ms pulse width = 45 degrees
  • 1.5ms pulse width = 90 degrees
  • 2.0ms pulse width = 135 degrees
  • 2.5ms pulse width = 180 degrees

DC Motor Control

A DC motor converts electrical energy into mechanical energy. It has two terminals; when connected with proper polarity, the motor rotates in one direction, and when polarity is reversed, it rotates in the opposite direction. Since DC motors are high-power devices, GPIO pins cannot drive them directly. A motor driver circuits required for operation. The TB6612 is a dual H-bridge DC motor driver chip capable of driving two DC motors while controlling their speed and direction.

Input Capture

Input Capture (IC) mode allows the timer to capture the counter value (CNT) and store it in the capture/compare register (CCR) when a specified edge transition occurs on the input pin. This functionality is useful for measuring PWM frequency, duty cycle, pulse intervals, and pulse duration.

Each advanced and general-purpose timer includes four input capture channels. The timers can be configured in PWMI mode to simultaneously measure frequency and duty cycle. When combined with master-slave trigger mode, hardware-based automatic measurement can be achieved.

Tags: STM32 Timer PWM Interrupt Servo Motor

Posted on Mon, 15 Jun 2026 17:49:19 +0000 by helloise