Microcontroller Basics
A microcontroller is a complete computer on one chip, built to control hardware. Learn its architecture — CPU, memory, clock, GPIO, timers, ADC, communication peripherals, interrupts and DMA — and how to budget power for battery devices.
A microcontroller (MCU) combines a processor core, flash memory for the program, RAM for data, and a rich set of peripherals — digital I/O pins, timers, analogue-to-digital converters, serial interfaces — on a single chip that costs anywhere from cents to a few dollars.
MCUs are inside washing machines, cars (dozens per vehicle), inverters, meters, drones and every IoT device. They read sensors, run control algorithms and drive actuators, often with hard real-time deadlines and tiny power budgets.
An analogy
An MCU is like a small factory: the CPU is the manager, flash is the instruction manual, RAM is the workbench, peripherals are specialised machines (timers, ADCs, UARTs) that work in parallel, and interrupts are the phone that rings when something needs attention.
What's inside
These blocks appear in almost every MCU.
- CPU core (8-bit AVR/PIC, 32-bit ARM Cortex-M, RISC-V).
- Flash (program) and SRAM (data), sometimes EEPROM.
- Clock system: internal RC or external crystal, PLL multiplier.
- GPIO pins configurable as input/output, pull-ups, alternate functions.
- Peripherals: timers/PWM, ADC/DAC, UART, SPI, I²C, CAN, USB.
- Interrupt controller (NVIC) and DMA.
GPIO electrical limits
Pins run at the MCU supply (3.3 V or 5 V) and can typically source/sink 4–25 mA each, with a total package limit. Driving LEDs directly is fine with a series resistor; relays, motors and solenoids need transistors or drivers. Inputs must never exceed the supply rail unless marked 5 V-tolerant.
Interrupts, timers and DMA
Interrupts let hardware events (a timer overflow, a byte received, a pin change) pre-empt the main loop immediately. Timers generate precise periodic events and PWM without CPU involvement. DMA moves data between peripherals and memory (ADC samples, UART buffers) while the CPU does other work.
Low-power design
Battery devices spend > 99 % of their time asleep. MCUs offer sleep, stop and standby modes drawing µA or nA, waking on timers or pins. Battery life depends on average current, so minimise wake time, run fast then sleep, and power down sensors between readings.
Choosing an MCU and the real-time view
Selection weighs core performance, memory, peripherals (e.g. motor-control timers, high-resolution ADCs, CAN-FD), package, power, toolchain and supply. Real-time behaviour depends on worst-case interrupt latency and execution time, not average speed; an RTOS helps structure complex firmware into prioritised tasks.
Formulas
- Timer tick:
f_tick = f_clk / (PSC + 1) - Timer period:
T = (ARR + 1) / f_tick - ADC voltage:
V = code × V_ref / 2ᴺ - Average current (duty-cycled):
I_avg = I_active·D + I_sleep·(1 − D) - Battery life:
t = capacity / I_avg
Worked example: 1-second timer
Given: f_clk = 72 MHz; PSC = 7199, ARR = 9999
Find: Tick rate and interrupt period.
- f_tick = 72e6/7200 = 10 kHz
- T = 10 000/10 kHz = 1.0 s
Answer: 10 kHz tick, 1 Hz interrupt
Worked example: Reading an ADC
Given: 12-bit ADC, V_ref = 3.3 V; Code = 2482
Find: Input voltage.
- V = 2482 × 3.3/4096 = 2.00 V
Answer: 2.00 V
Toggling an LED from a timer interrupt (STM32-style C)
#include "stm32f1xx.h"
void TIM2_IRQHandler(void) {
if (TIM2->SR & TIM_SR_UIF) { // update (overflow) event?
TIM2->SR &= ~TIM_SR_UIF; // clear the flag
GPIOC->ODR ^= (1u << 13); // toggle PC13 (on-board LED)
}
}
int main(void) {
RCC->APB2ENR |= RCC_APB2ENR_IOPCEN; // clock GPIOC
RCC->APB1ENR |= RCC_APB1ENR_TIM2EN; // clock TIM2
GPIOC->CRH = (GPIOC->CRH & ~(0xFu << 20)) | (0x2u << 20); // PC13 output 2 MHz
TIM2->PSC = 7200 - 1; // 72 MHz / 7200 = 10 kHz tick
TIM2->ARR = 10000 - 1; // 10 000 ticks = 1 s
TIM2->DIER |= TIM_DIER_UIE;
NVIC_EnableIRQ(TIM2_IRQn);
TIM2->CR1 |= TIM_CR1_CEN; // start
for (;;) { __WFI(); } // sleep until the next interrupt
}The timer runs in hardware; the CPU sleeps (WFI) and wakes only for the 1 Hz interrupt — the core pattern of efficient firmware.
Common mistakes
- Wrong: Driving a relay coil directly from a GPIO pin. — Right: Use a transistor/MOSFET and a flyback diode; the pin can't supply the current and the inductive kick destroys it.
- Wrong: Doing heavy work inside interrupt handlers. — Right: Keep ISRs short: set a flag or buffer data, and process it in the main loop or a task.
Applications
- Motor control: Motor-control MCUs have complementary PWM timers with dead time, fast ADCs synchronised to PWM and FOC math accelerators.
- Smart meters: Ultra-low-power MCUs with metrology front-ends run for 15+ years.
- Automotive ECUs: Safety-certified MCUs with lockstep cores run engine, braking and battery management.
Key takeaways
- An MCU = CPU + flash + RAM + peripherals on one chip.
- Timers, interrupts and DMA do real-time work in hardware.
- Respect GPIO limits — use drivers for real loads.
- Battery life = capacity/average current; sleep aggressively.
Going further
- Memory-mapped peripherals: Peripherals appear as registers at fixed addresses; the CMSIS headers define structs so TIM2->ARR compiles to a single store instruction.
- Bootloaders and OTA: A bootloader in protected flash can verify and install new firmware received over UART, USB or radio, with dual-bank flash allowing rollback if the update fails.
- Functional safety: ISO 26262 / IEC 61508 MCUs add lockstep cores, ECC memory, clock monitors and self-tests so hardware faults are detected within defined time limits.