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.
PWM generation using timers in 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.
// Example for a generic 8-bit timer TIMER_MODE = PWM_MODE; TIMER_PERIOD = 255; // max count TIMER_COMPARE = 128; // 50% duty cycle TIMER_START();
// 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
This program sets up Timer0 on an AVR microcontroller to generate a 50% duty cycle PWM signal on pin PD6.
#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; }
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.
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
Solution
Step 1: Understand the acronym PWM
PWM is a common term in embedded systems related to signal control.Step 2: Match PWM with its full form
PWM stands for Pulse Width Modulation, which controls signal timing using timers.Final Answer:
Pulse Width Modulation -> Option AQuick Check:
PWM = Pulse Width Modulation [OK]
- Confusing PWM with power management terms
- Thinking PWM is a mode for writing data
- Mixing PWM with watchdog timer functions
Solution
Step 1: Identify standard embedded C HAL function
HAL libraries use the prefix HAL_TIM_PWM_Start for starting PWM timers.Step 2: Check syntax correctness
HAL_TIM_PWM_Start(&htim); uses correct syntax with a timer handle pointer, matching HAL style.Final Answer:
HAL_TIM_PWM_Start(&htim); -> Option BQuick Check:
HAL_TIM_PWM_Start(&htim) is correct syntax [OK]
- Using incorrect function names without HAL prefix
- Missing the timer handle argument
- Using lowercase or camelCase incorrectly
uint32_t period = 1000; uint32_t pulse = 250; // Timer configured with period and pulse // PWM output uses pulse width = pulse
Solution
Step 1: Understand duty cycle formula
Duty cycle = (pulse / period) * 100%Step 2: Calculate duty cycle with given values
Duty cycle = (250 / 1000) * 100% = 25%Final Answer:
25% -> Option DQuick Check:
Duty cycle = 25% [OK]
- Confusing pulse with period
- Calculating 1000/250 instead of 250/1000
- Forgetting to multiply by 100 for percentage
TIM_HandleTypeDef htim; htim.Init.Period = 1000; htim.Init.Pulse = 500; HAL_TIM_PWM_Start(&htim);
Solution
Step 1: Check PWM initialization sequence
Before starting PWM, the channel must be configured with pulse value using HAL_TIM_PWM_ConfigChannel.Step 2: Identify missing configuration call
The code sets pulse in Init (which is incorrect) and skips HAL_TIM_PWM_ConfigChannel call.Final Answer:
Missing call to HAL_TIM_PWM_ConfigChannel before starting PWM -> Option AQuick Check:
ConfigChannel call needed before HAL_TIM_PWM_Start [OK]
- Setting pulse in Init structure instead of channel config
- Starting PWM without configuring channel
- Assuming timer handle must be pointer variable
Solution
Step 1: Calculate timer frequency after prescaler
Timer clock = 72 MHz / (71 + 1) = 1 MHz (1 microsecond per tick)Step 2: Calculate period for 1 kHz PWM frequency
Period = (Timer frequency / PWM frequency) - 1 = (1,000,000 / 1,000) - 1 = 999Step 3: Calculate pulse for 60% duty cycle
Pulse = Period * 0.6 = 999 * 0.6 = 599.4 ≈ 600Final Answer:
Period = 999, Pulse = 600 -> Option CQuick Check:
Period 999 and pulse 600 give 60% duty cycle at 1 kHz [OK]
- Not adding 1 to prescaler or period calculations
- Using full clock without prescaler division
- Rounding pulse incorrectly
Ready to prove it?
Pass the test and this pattern moves unknown
