Bird
Raised Fist0
Embedded Cprogramming~5 mins

PWM generation using timers in Embedded C

Choose your learning style10 modes available
Introduction

PWM (Pulse Width Modulation) lets us control devices like motors or LEDs by turning a signal on and off very fast. Using timers helps create this signal automatically and precisely.

To control the brightness of an LED by changing how long it stays on.
To adjust the speed of a motor smoothly.
To generate audio tones by varying the signal.
To control servo motors in robotics.
To create precise timing signals for communication.
Syntax
Embedded C
1. Configure the timer's mode to PWM.
2. Set the timer's period (frequency).
3. Set the duty cycle (how long signal stays high).
4. Start the timer to begin PWM output.

The exact code depends on your microcontroller and its timer registers.

Duty cycle is usually set by changing the compare register value.

Examples
This sets a PWM with 50% duty cycle on an 8-bit timer.
Embedded C
// Example for a generic 8-bit timer
TIMER_MODE = PWM_MODE;
TIMER_PERIOD = 255; // max count
TIMER_COMPARE = 128; // 50% duty cycle
TIMER_START();
Using STM32 HAL, this starts PWM on channel 1 with 50% duty cycle.
Embedded C
// Example for STM32 HAL library
TIM_HandleTypeDef htim;
htim.Init.Prescaler = 0;
htim.Init.Period = 999;
HAL_TIM_PWM_Start(&htim, TIM_CHANNEL_1);
__HAL_TIM_SET_COMPARE(&htim, TIM_CHANNEL_1, 500); // 50% duty
Sample Program

This program sets up Timer0 on an AVR microcontroller to generate a 50% duty cycle PWM signal on pin PD6.

Embedded C
#include <avr/io.h>

int main(void) {
    // Set PD6 (OC0A) as output
    DDRD |= (1 << PD6);

    // Set Timer0 to Fast PWM mode
    TCCR0A |= (1 << WGM01) | (1 << WGM00);
    TCCR0B |= (1 << CS00); // No prescaling

    // Set non-inverting mode on OC0A
    TCCR0A |= (1 << COM0A1);

    // Set duty cycle to 50%
    OCR0A = 128;

    while(1) {
        // PWM runs automatically
    }

    return 0;
}
OutputSuccess
Important Notes

Make sure the output pin is set as output in the data direction register.

Changing the OCR (Output Compare Register) value changes the duty cycle.

Timer prescaler affects PWM frequency; choose it based on your needs.

Summary

PWM uses timers to create signals that switch on and off quickly.

Duty cycle controls how long the signal stays on in each cycle.

Setting timer mode, period, and compare value generates PWM automatically.

Practice

(1/5)
1. What does PWM stand for in embedded C programming when using timers?
easy
A. Pulse Width Modulation
B. Power Wave Management
C. Programmed Write Mode
D. Peripheral Watchdog Monitor

Solution

  1. Step 1: Understand the acronym PWM

    PWM is a common term in embedded systems related to signal control.
  2. Step 2: Match PWM with its full form

    PWM stands for Pulse Width Modulation, which controls signal timing using timers.
  3. Final Answer:

    Pulse Width Modulation -> Option A
  4. Quick Check:

    PWM = Pulse Width Modulation [OK]
Hint: Remember PWM controls signal timing by pulse width [OK]
Common Mistakes:
  • Confusing PWM with power management terms
  • Thinking PWM is a mode for writing data
  • Mixing PWM with watchdog timer functions
2. Which of the following is the correct way to start a timer for PWM in embedded C?
easy
A. TIM_StartPWM();
B. HAL_TIM_PWM_Start(&htim);
C. StartTimerPWM();
D. timer_pwm_start();

Solution

  1. Step 1: Identify standard embedded C HAL function

    HAL libraries use the prefix HAL_TIM_PWM_Start for starting PWM timers.
  2. Step 2: Check syntax correctness

    HAL_TIM_PWM_Start(&htim); uses correct syntax with a timer handle pointer, matching HAL style.
  3. Final Answer:

    HAL_TIM_PWM_Start(&htim); -> Option B
  4. Quick Check:

    HAL_TIM_PWM_Start(&htim) is correct syntax [OK]
Hint: HAL functions start with HAL_ prefix and use handles [OK]
Common Mistakes:
  • Using incorrect function names without HAL prefix
  • Missing the timer handle argument
  • Using lowercase or camelCase incorrectly
3. Given the following code snippet, what is the duty cycle percentage of the PWM signal?
uint32_t period = 1000;
uint32_t pulse = 250;
// Timer configured with period and pulse
// PWM output uses pulse width = pulse
medium
A. 100%
B. 75%
C. 50%
D. 25%

Solution

  1. Step 1: Understand duty cycle formula

    Duty cycle = (pulse / period) * 100%
  2. Step 2: Calculate duty cycle with given values

    Duty cycle = (250 / 1000) * 100% = 25%
  3. Final Answer:

    25% -> Option D
  4. Quick Check:

    Duty cycle = 25% [OK]
Hint: Duty cycle = pulse divided by period times 100% [OK]
Common Mistakes:
  • Confusing pulse with period
  • Calculating 1000/250 instead of 250/1000
  • Forgetting to multiply by 100 for percentage
4. Identify the error in this PWM timer initialization code snippet:
TIM_HandleTypeDef htim;
htim.Init.Period = 1000;
htim.Init.Pulse = 500;
HAL_TIM_PWM_Start(&htim);
medium
A. Missing call to HAL_TIM_PWM_ConfigChannel before starting PWM
B. The 'Pulse' field requires pointer syntax like htim->Init.Pulse
C. Period value should be set after starting PWM
D. Timer handle 'htim' must be a pointer, not a variable

Solution

  1. Step 1: Check PWM initialization sequence

    Before starting PWM, the channel must be configured with pulse value using HAL_TIM_PWM_ConfigChannel.
  2. Step 2: Identify missing configuration call

    The code sets pulse in Init (which is incorrect) and skips HAL_TIM_PWM_ConfigChannel call.
  3. Final Answer:

    Missing call to HAL_TIM_PWM_ConfigChannel before starting PWM -> Option A
  4. Quick Check:

    ConfigChannel call needed before HAL_TIM_PWM_Start [OK]
Hint: Always configure PWM channel before starting timer [OK]
Common Mistakes:
  • Setting pulse in Init structure instead of channel config
  • Starting PWM without configuring channel
  • Assuming timer handle must be pointer variable
5. You want to generate a PWM signal with a 60% duty cycle and a frequency of 1 kHz using a timer with a 72 MHz clock. Which timer period and pulse values should you set? Assume timer prescaler is set to 71 (divides clock by 72).
hard
A. Period = 1000, Pulse = 600
B. Period = 72000, Pulse = 43200
C. Period = 999, Pulse = 600
D. Period = 71, Pulse = 43

Solution

  1. Step 1: Calculate timer frequency after prescaler

    Timer clock = 72 MHz / (71 + 1) = 1 MHz (1 microsecond per tick)
  2. Step 2: Calculate period for 1 kHz PWM frequency

    Period = (Timer frequency / PWM frequency) - 1 = (1,000,000 / 1,000) - 1 = 999
  3. Step 3: Calculate pulse for 60% duty cycle

    Pulse = Period * 0.6 = 999 * 0.6 = 599.4 ≈ 600
  4. Final Answer:

    Period = 999, Pulse = 600 -> Option C
  5. Quick Check:

    Period 999 and pulse 600 give 60% duty cycle at 1 kHz [OK]
Hint: Divide clock by prescaler, then calculate period and pulse [OK]
Common Mistakes:
  • Not adding 1 to prescaler or period calculations
  • Using full clock without prescaler division
  • Rounding pulse incorrectly
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard