Introduction
In embedded systems, software communicates directly with hardware peripherals such as GPIO pins, timers, UART modules, ADCs, and communication interfaces. These peripherals are controlled using hardware registers, which are special memory locations mapped to fixed addresses.
Most microcontrollers use memory-mapped I/O, where hardware registers are accessed like normal memory using pointers in C.
What is a Register?
A register is a small hardware-controlled memory location used to configure, control, or monitor peripherals.
Registers are commonly used to:
- • enable or disable peripherals
- • configure hardware settings
- • store status information
- • transfer hardware data
Each register is assigned a unique memory address inside the system memory map.
Memory-Mapped I/O
In memory-mapped systems, specific memory addresses are reserved for hardware peripherals.
Address Peripheral Register
0x40000000 → GPIO Register
0x40000004 → UART Register
0x40000008 → Timer Register
Reading or writing to these addresses directly affects the associated hardware.
Accessing Registers Using Pointers
Pointers are used to access hardware registers through their memory addresses.
Example
unsigned int *GPIO =
(unsigned int *)0x40000000;
Here:
- •
0x40000000is the register address - • the pointer stores this address
- • dereferencing the pointer accesses the actual hardware register
Writing to a Register
*GPIO = 0x01;
This writes data directly into the hardware register.
Reading from a Register
unsigned int value = *GPIO;
This reads the current register value from hardware.
Register Bit Manipulation
Bitwise operators are commonly used to control specific register bits.
*GPIO |= (1 << 3);
This sets bit 3 while keeping other bits unchanged.
Example Program
#include <stdio.h>
int main()
{
unsigned int *GPIO =
(unsigned int *)0x40000000;
*GPIO = 0x01;
return 0;
}
How It Works
The pointer stores the hardware register address. When the pointer is dereferenced using *, the program directly accesses that physical hardware location. The processor then performs a real hardware read or write operation on the peripheral register.
Important Points
- → Hardware peripherals are controlled through registers
- → Registers are mapped to fixed memory addresses
- → Pointers allow direct hardware access
- → Register operations commonly use bitwise operators
- → Reading and writing register values directly affects hardware behavior
Why This Matters in Embedded Systems
Register-level programming is one of the core foundations of embedded development. Almost all embedded firmware interacts directly with memory-mapped registers to configure peripherals, handle interrupts, control communication interfaces, and manage hardware behavior.
UART_CTRL |= (1 << 0);
Understanding registers and memory mapping is essential for low-level firmware development and microcontroller programming.