0
0
Power-electronicsHow-ToBeginner · 3 min read

How to Use Pointer to Register in Embedded C: Simple Guide

In Embedded C, you use a pointer to access a hardware register by assigning the register's memory address to a pointer variable declared as volatile. This lets you read or write the register directly through the pointer, ensuring the compiler does not optimize away these accesses.
📐

Syntax

To use a pointer to a hardware register, declare a volatile pointer to the register's address. The volatile keyword tells the compiler the value can change anytime, so it must not optimize access.

Example parts:

  • volatile: prevents compiler optimizations
  • uint32_t *: pointer to a 32-bit unsigned register
  • 0x40021000: example register address
  • = (volatile uint32_t *)0x40021000;: cast address to pointer type
c
volatile uint32_t *reg_ptr = (volatile uint32_t *)0x40021000;
💻

Example

This example shows how to write a value to a hardware register and then read it back using a pointer. It simulates a register at a fixed memory address.

c
#include <stdint.h>
#include <stdio.h>

// Simulate hardware register memory
uint32_t simulated_register = 0;

int main() {
    // Pointer to the simulated register address
    volatile uint32_t *reg_ptr = &simulated_register;

    // Write a value to the register
    *reg_ptr = 0xABCD1234;

    // Read the value back
    uint32_t value = *reg_ptr;

    printf("Register value: 0x%X\n", value);
    return 0;
}
Output
Register value: 0xABCD1234
⚠️

Common Pitfalls

Common mistakes when using pointers to registers include:

  • Not using volatile, causing the compiler to optimize away register reads/writes.
  • Using incorrect pointer types or sizes, leading to wrong data access.
  • Forgetting to cast the register address to the correct pointer type.
  • Accessing invalid memory addresses causing crashes.

Always verify the register address and use volatile to ensure proper hardware access.

c
/* Wrong: Missing volatile - compiler may optimize away access */
uint32_t *reg_ptr_wrong = (uint32_t *)0x40021000;
*reg_ptr_wrong = 0x01; // May not actually write to hardware

/* Correct: Use volatile to prevent optimization */
volatile uint32_t *reg_ptr_right = (volatile uint32_t *)0x40021000;
*reg_ptr_right = 0x01; // Guaranteed write to hardware
📊

Quick Reference

ConceptDescriptionExample
volatilePrevents compiler optimization on register accessvolatile uint32_t *reg_ptr;
Pointer castCast address to pointer type for correct access(volatile uint32_t *)0x40021000
DereferenceRead or write register via pointer*reg_ptr = 0x01;
AddressUse correct hardware register address0x40021000

Key Takeaways

Always declare register pointers as volatile to prevent compiler optimizations.
Cast the hardware register address to the correct pointer type before use.
Use pointers to read from and write to hardware registers directly.
Verify register addresses carefully to avoid invalid memory access.
Dereference the pointer to access the register value safely.