These five peripherals are the backbone of embedded work. Here’s a practical, no-nonsense cheat sheet with concepts, setup steps, and tiny code examples (Arduino & STM32 HAL) you can drop into a project.
Image Not Showing
Possible Reasons
- The image was uploaded to a note which you don't have access to
- The note which the image was originally uploaded to has been deleted
Learn More →
Big picture
- ADC: converts analog voltage → digital number
- DAC: converts digital number → analog voltage/current
- PWM: digital pin toggled with a duty cycle to emulate analog power
- Timers: hardware counters for timebases, PWM, captures, periodic interrupts
- UART: async serial byte stream (TX/RX) for logs, modules, PCs
ADC (Analog-to-Digital Converter)
Key params: resolution (n bits), reference (Vref), sampling time, input impedance, rate
LSB size: LSB = Vref / 2^n (e.g., 12-bit @3.3V → 0.805 mV)
Typical setup
- Select channel/pin, set it as analog input (no pull-ups).
- Pick Vref (internal/external).
- Configure sample time to allow the pin to settle (depends on source impedance).
- Choose single/continuous/scan, optionally enable DMA.
- Start conversion, read result (poll/interrupt/DMA).
Arduino example (UNO, 10-bit, A0)
STM32 HAL (single channel, polling)
Gotchas & tips
- Buffer high-impedance sensors with an op-amp or increase sample time.
- Keep analog ground/trace short; add 100 nF near Vref and sensor.
- For noise: oversample/average, or use DMA + moving average.
DAC (Digital-to-Analog Converter)
Key params: resolution, output buffer, settling time, output range (often 0..Vref)
Use cases: audio tones, bias voltages, reference levels, slow waveforms.
STM32 HAL (write a value)
Arduino “DAC” note: many Arduinos lack true DAC; use analogWrite() (PWM) + RC filter, or boards with DAC (e.g., Arduino Due, Nano 33 BLE Sense, Teensy).
Tip: For smooth waveforms, feed DAC by DMA from a lookup table, triggered by a timer.
PWM (Pulse-Width Modulation)
Concept: Digital pin toggles at frequency fPWM with duty cycle D%. Average voltage ≈ D · Vcc (after filtering or for power control).
Frequency calculation (general timer):
fPWM = f_timer_clk / (Prescaler + 1) / (ARR + 1)
Duty (edge-aligned): CCR / ARR
Arduino
STM32 HAL (Timer PWM)
Tips
- For motors/LEDs, choose kHz to tens of kHz to avoid audible flicker/whine.
- Use hardware PWM (timer channels), not bit-banging.
- For dimming LEDs linearly to the eye, apply gamma correction in software.
Timers
Modes: up/down counting, PWM generation, input capture (timestamp edges), output compare (toggle/interrupt), encoder mode, one-pulse.
Create a periodic interrupt
Arduino
STM32 HAL (1 kHz tick using TIMx + IRQ)
Input capture (period/frequency measurement)
Configure channel in capture mode; on each edge, read CCRx; delta counts → period.
Tips
- Derive all periodic tasks from timers (not delay()), especially for control loops.
- Check clock tree: APB prescalers affect timer clocks (sometimes ×2 on STM32).
UART (Serial)
Params: baud, data bits, parity, stop bits (e.g., 115200 8N1).
Flow control: none/RTS/CTS; use it for high baud rates or long bursts.
Arduino
STM32 HAL (blocking & DMA)
Tips
- Start with conservative baud (9600/115200), then raise.
- For binary protocols, add framing (start byte, length, CRC) or use SLIP/CBOR/CBUS.
- Enable DMA or ring buffers for continuous streams.
Common patterns that combine peripherals
- ADC via DMA + Timer trigger: fixed-rate sampling without CPU jitter.
- DAC via DMA + Timer: waveform generation (sine, chirp).
- PWM + Timer interrupt: closed-loop motor/LED control.
- UART + DMA: high-throughput logging or module control.
Quick troubleshooting checklist
- Wrong pin alt-function? (GPIO vs AF for timers/UART)
- Clock not enabled for peripheral/bus? (RCC on STM32)
- Interrupt not enabled/priorities wrong?
- Reference voltage or grounds missing for ADC/DAC?
- For PWM: ARR/PSC combo yields wrong frequency?
- UART cable cross: TX↔RX, and common ground present?