MCU Registers
A processor register
is a quickly accessible location available to a computer's processor.
Registers usually consist of a small amount of fast storage, although some registers have specific hardware functions, and may be read-only or write-only.
Its used to store data, operands, calculation results, memory addressing, peripheral control, and microcontroller operation during instruction execution.
Each register has a specific function and bit capacity.
🟠 When performing an arithmetic operation, the processor may load the operands into general-purpose registers, perform the operation, and then store the result in another register or in memory.
📌 Why registers are important
- They are the fastest way to access information and allow operations to be performed without accessing external
RAM
memory. - Almost every microprocessor
command
relies on the use of registers. - Setting up the microcontroller
peripherals
directly depends on writing to control registers.
🧩 Basic types of registers
Type | Purpose | Examples |
---|---|---|
General-purpose registers (GPR) | * Stores data and intermediate values and adresses * When adding numbers, the processor loads the values from `RAM` into registers, performs the operation and stores the result back. | R0–R31 (AVR), EAX–EDX (x86), R0–R12 (ARM) |
Special-purpose registers (SFR) | * Hold some elements of the program state * Each SFR has a **fixed address** in memory and is controlled by software * They usually include the program counter, also called the instruction pointer * Microcontrollers, can also have special function registers corresponding to specialized hardware elements.(timers, UART, ADC, etc.) | TCCR0 , ADCSRA , USART_CR |
Address Registers | * Hold addresses and are used by instructions that indirectly access primary memory. | SP , BP , SI , DI , X , Y , Z |
Data Registers | * Can hold numeric data values such as `integers` and, (in some architectures `floating-point` numbers), as well as `characters`, small `bit arrays` and other data for I/O | PORTx , PINx , DDRx |
Status (Flag) Registers Condition code register (CCR) | * Contain bits of the flags of the operation result * Hold truth values often used to determine whether some instruction should or should not be executed. | SREG , CPSR , FLAGS |
Hardware registers | * Used in the interface between software and peripherals | * Input/output (I/O) of different kinds * Configuration and start-up of certain features, especially during initialization * Used to interact with physical pins of the microcontroller: reading/writing levels, configuring directions, etc. |
Command registers (IP/PC) * not accessible by instructions and are used internally for processor operations | Point to the currently executing instruction | PC , EIP , R15 |
Segment registers * not accessible by instructions and are used internally for processor operations | Point to memory segments (x86) | CS , DS , SS , ES |
🛠 Example: Setting up SysTick (ARM Cortex-M)
To manually set up the system timer (SysTick) three registers are used:
Register Name | Purpose | Address |
---|---|---|
SYST_CSR | Control and Status | 0xE000E010 |
SYST_RVR | Reset Value | 0xE000E014 |
SYST_CVR | Current Value | 0xE000E018 |
-
The
SYST_CSR
register enables the SysTick features. It has three parameters that we are interested in:clock source
(which specifies what clock rates the timer should support),tick interrupt enable
(which allows an interrupt to fire when the timer reaches zero) andenabling the timer itself
The parameters are controlled by the three least significant bits in our32-bit
register.
So for example, if you wanted to set all values to one, our 32 bits would look like this. (00000000_00000000_00000000_000000111
) The last three bits are set to one.
-
The
SYST_RVR
register specifies the start value to load into theSYST_CVR
register.
It counts down from that value tozero
.
It's a 24-bit register, so the total number of values we have is about16.7 million.
-
The
SYST_CVR
register contains the current value of the counter.
If the timer restarted with a reset value of250
and100
ticks have passed, the current value will be150
.
You can go to this register to clear the value.
It is good practice to clear this register before enabling the timer so that its value makes sense when you read it.
Rust example:
const SYST_CSR: u32 = 0xE000E010;
const SYST_RVR: u32 = 0xE000E014;
const SYST_CVR: u32 = 0xE000E018;
let sleep_dur = CPU_FREQ; // duration = 1 second
unsafe {
*(SYST_RVR as *mut u32) = sleep_dur; // set timer duration
*(SYST_CVR as *mut u32) = 0; // set current value to 0
*(SYST_CSR as *mut u32) = 0b111; // set source, enable timer and interrupts
}