ADC (analog-to-digital read)
Embedded → Analog & Serial Peripherals (HAL)
The real world is analog — your MCU only understands bits
A potentiometer, thermistor, or mic produces a continuously-varying voltage, not a clean 0/1 a GPIO register can read. An ADC samples that voltage and reports an integer — the ADC count — representing where it fell within the measurable range. How faithfully that integer represents the real voltage comes down to two numbers: resolution and reference.
Resolution and reference are the whole story
| Term | Meaning |
|---|---|
| Resolution | distinct output codes — 12-bit = 2^12 = 4096 counts, 10-bit = 1024. More bits = finer voltage steps |
| Reference (Vref) | voltage mapping to the max count — a reading of 0 = 0V, max count = Vref, everything between linearly interpolated. A noisy/drifting Vref scales every reading by the same error |
Vin = ADC_count × (Vref / (2^N − 1)) // 12-bit ADC, Vref = 3.3V, count = 2048: Vin = 2048 × (3.3 / 4095) ≈ 1.65V
Sampling time — the ADC needs a moment to charge
Most ADCs charge a small sample-and-hold capacitor to the input voltage before converting. If the source can't supply enough current to charge it within the sampling window, the reading comes out low/lagging — a classic high-impedance-source (e.g. a thermistor divider with large resistors) symptom. Fix with a longer sample-time setting or a buffer op-amp — not fixable in software after the fact.
Reading it — STM32 HAL, single-channel polling
ADC_HandleTypeDef hadc1;
HAL_ADC_Start(&hadc1);
HAL_ADC_PollForConversion(&hadc1, HAL_MAX_DELAY);
uint32_t raw = HAL_ADC_GetValue(&hadc1); // 0 .. 4095 on a 12-bit ADC
float vref = 3.3f;
float vin = raw * (vref / 4095.0f);
printf("raw=%lu vin=%.3fV\r\n", raw, vin);Polling is fine for a one-off reading, but it blocks the CPU until the conversion finishes. Sampling a signal continuously at a fixed rate — a potentiometer at 1kHz, an audio input far faster — is exactly the case the next lesson (DMA) exists to solve: let the ADC free-run and have a peripheral move each finished sample into a buffer with zero CPU involvement per sample.
Try it — resolution, reference, and quantization error
Drag Vin and switch resolution/Vref — watch the ADC count and the quantization error it introduces:
Practice
Completion saves automatically after you read through to the end.
Next lesson →