What are timers in STM32, and how are they configured?
Timers in STM32 microcontrollers are versatile peripherals used for timing, PWM generation, input capture, output compare, and more. They are essential for tasks like motor control, sensor interfacing, and real-time operations. Here’s a comprehensive guide to STM32 timers and their configuration:
1. Types of Timers in STM32
STM32 timers are categorized based on their features:
| Timer Type | Key Features | Examples |
|---|---|---|
| Basic Timer | Simple counting, no I/O pins. Used for time-base generation. | TIM6, TIM7 |
| General-Purpose | PWM, input capture, output compare. Suitable for most timing tasks. | TIM2, TIM3, TIM4, TIM5 |
| Advanced Timer | Complementary PWM, dead-time insertion (for motor control). | TIM1, TIM8 (STM32F1/F4) |
| Low-Power Timer | Ultra-low-power operation (used in STOP mode). | LPTIM1, LPTIM2 |
2. Key Timer Features
Clock Sources: Internal (APB bus), external clock, or other timers.
Count Modes: Up, Down, Up/Down (Center-aligned).
Channels: Input capture (measure pulse width) / output compare (generate signals).
PWM Generation: Variable frequency/duty cycle.
Interrupts/DMA: Trigger events on overflow, capture, or compare matches.
3. Timer Configuration Steps
A. Clock Enable
Enable the timer clock via the RCC (Reset and Clock Control) module:
__HAL_RCC_TIM2_CLK_ENABLE(); // For TIM2 (HAL Library)
B. Initialize Timer Parameters
Configure using HAL (for STM32CubeIDE) or direct register access.
Example: Basic Timer (TIM2) in PWM Mode
TIM_HandleTypeDef htim2; void MX_TIM2_Init(void) { htim2.Instance = TIM2; htim2.Init.Prescaler = 79; // Clock divider (80 MHz / (79+1) = 1 MHz) htim2.Init.CounterMode = TIM_COUNTERMODE_UP; // Count up htim2.Init.Period = 999; // Auto-reload value (1 MHz / 1000 = 1 kHz PWM) htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; HAL_TIM_PWM_Init(&htim2); }
C. Configure PWM Channel
TIM_OC_InitTypeDef sConfigOC; sConfigOC.OCMode = TIM_OCMODE_PWM1; // PWM mode 1 (active high) sConfigOC.Pulse = 500; // Duty cycle = 500/1000 = 50% sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH; // Output polarity sConfigOC.OCFastMode = TIM_OCFAST_DISABLE; // No fast mode HAL_TIM_PWM_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_1);
D. Start the Timer
HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_1); // Start PWM on Channel 1
4. Common Timer Modes
A. Input Capture (Measure Pulse Width)
Use Case: Measure frequency/duty cycle of an external signal.
Configuration:
TIM_IC_InitTypeDef sConfigIC; sConfigIC.ICPolarity = TIM_ICPOLARITY_RISING; // Trigger on rising edge sConfigIC.ICSelection = TIM_ICSELECTION_DIRECTTI; sConfigIC.ICPrescaler = TIM_ICPSC_DIV1; // No prescaler sConfigIC.ICFilter = 0; // No noise filter HAL_TIM_IC_ConfigChannel(&htim2, &sConfigIC, TIM_CHANNEL_1); HAL_TIM_IC_Start_IT(&htim2, TIM_CHANNEL_1); // Start with interrupts
B. Output Compare (Generate Delayed Events)
Use Case: Trigger an action after a specific time.
Configuration:
TIM_OC_InitTypeDef sConfigOC; sConfigOC.OCMode = TIM_OCMODE_TOGGLE; // Toggle output on match sConfigOC.Pulse = 200; // Compare value HAL_TIM_OC_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_2); HAL_TIM_OC_Start(&htim2, TIM_CHANNEL_2);
C. Encoder Mode (Read Quadrature Encoders)
Use Case: Track rotary encoder position/speed.
Configuration:
TIM_Encoder_InitTypeDef sEncoderConfig; sEncoderConfig.EncoderMode = TIM_ENCODERMODE_TI12; // Count both edges sEncoderConfig.IC1Polarity = TIM_ICPOLARITY_RISING; sEncoderConfig.IC2Polarity = TIM_ICPOLARITY_RISING; HAL_TIM_Encoder_Init(&htim2, &sEncoderConfig); HAL_TIM_Encoder_Start(&htim2, TIM_CHANNEL_ALL);
5. Calculating Timer Parameters
Timer Clock (MHz): APB clock (check
SystemCoreClockin HAL).PWM Frequency:
PWM_Freq = Timer_Clock / ((Prescaler + 1) * (Period + 1))
Example: 80 MHz clock, prescaler=79, period=999 → 1 kHz PWM.
PWM Duty Cycle:
Duty_Cycle (%) = (Pulse / (Period + 1)) * 100
6. Advanced Features
Burst Mode: Update multiple registers in one operation.
DMA with Timers: Offload data transfers (e.g., PWM waveform buffers).
One-Pulse Mode: Generate a single pulse on trigger.
7. Debugging Tips
Check Clock Settings: Ensure the timer clock is enabled and correctly sourced.
Verify GPIO Alternate Function:
GPIO_InitStruct.Alternate = GPIO_AF1_TIM2; // TIM2_CH1 on PA0 (STM32F4)
Use Logic Analyzers: Probe PWM/output compare signals.
Monitor Registers: Use debuggers to check
TIMx->CNT(counter value).
8. Example: PWM Generation on STM32CubeIDE
Open STM32CubeMX, select your MCU.
Enable TIM2 and set a channel to PWM Generation CH1.
Configure:
Prescaler: 79 (for 1 MHz timer clock if APB1=80 MHz).
Counter Period: 999 (1 kHz PWM).
Generate code and add:
HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_1); __HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_1, 500); // 50% duty cycle
9. Register-Level Configuration (Bare-Metal)
For minimal latency:
TIM2->PSC = 79; // Prescaler TIM2->ARR = 999; // Auto-reload TIM2->CCR1 = 500; // Duty cycle (PWM) TIM2->CCMR1 |= TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_2; // PWM mode TIM2->CR1 |= TIM_CR1_CEN; // Enable timer
10. Common Pitfalls
Clock Mismatch: APB1 vs. APB2 timers (check clock tree).
Period Overflow: Ensure
(Period + 1)fits in 16/32 bits.GPIO Conflicts: Verify alternate function mappings in the datasheet.
Summary
Basic Timers: Simple delays/timeouts.
General-Purpose: PWM, input capture, output compare.
Advanced Timers: Motor control with complementary outputs.
Low-Power Timers: Battery-sensitive applications.
For precise timing, always validate with an oscilloscope or logic analyzer.

评论
发表评论