Microcontroller/microprocessor architecture and interfacing
Scope of the domain
This domain tests the processor core and its peripheral connections: architecture, instruction cycle, addressing modes, memory-mapped I/O, interrupts, timers, serial buses and GPIO interfacing.
Core rules
- Von Neumann architecture shares one memory space for code and data; Harvard architecture uses separate program and data memories and can fetch instructions and data simultaneously.
- The instruction cycle is fetch, decode, execute. The stack stores return addresses and saved context; interrupts push context and jump through a vector.
- Memory-mapped I/O places peripherals in the address space; port-mapped I/O uses separate instructions and address space.
- Interrupt latency is the time from the request to the first ISR instruction. ISRs should be short and use volatile for shared variables.
- UART with 16× oversampling: divisor = fclock/(16 × baud). SPI is full-duplex and synchronised by CPOL and CPHA; I2C uses open-drain lines with pull-ups, addressing and acknowledge bits.
- GPIO pins have current limits; a series resistor and a driver transistor protect the port when driving LEDs or relays.
Worked example
An 8 MHz microcontroller UART must run at 9600 baud with 16× oversampling. Divisor = 8,000,000/(16 × 9600) = 52.08, so program 52. Actual baud = 8,000,000/(16 × 52) = 9615.4, an error of (9615.4 - 9600)/9600 = 0.16%, well within the few-percent tolerance of asynchronous reception. If the divisor were rounded to 53, the baud would be 9434 and the error about 1.7%, still often usable but closer to the limit. Always calculate the error rather than assuming the nominal divisor is exact.
Traps that cost marks
Forgetting the 16× factor in the UART divisor; mixing SPI modes by using the wrong CPOL/CPHA pair; omitting I2C pull-ups; doing lengthy work inside an ISR; missing volatile on variables changed by an ISR; and exceeding GPIO source or sink current.