assign a variable name to a register address

What does this mean? (*(volatile unsigned char *)(0x22))

Using C, I was trying to assign a variable name to a register address so that my code would be readable. An example of how to do this is as follows:

#define DDRA (*(volatile unsigned char *)(0x22))

This means that if a register or memory location exists at address 0x22, I can
use DDRA to read or write to it like so..

DDRA = 0x05

in my C code.
The #define looks really cryptic at first. The way to understand this is by breaking it down into pieces. First of all,

unsigned char

means we are using a byte-sized memory location. Byte being 8-bits wide.

unsigned char *

means we are declaring a pointer that points to a byte-sized location.

(unsigned char *) (0x22)

means the byte-sized pointer points to address 0x22. The C compiler will refer to address 0x22 when the variable DDRA is used. The assembly code will end up using 0x22 in Load(LD) and Store (STR) insturctions.

(*(unsigned char *)(0x22))

The first asterisk from the left signifies that we want to manipulate the value in address 0x22. * means “the value pointed to by the pointer”.

volatile

volatile forces the compiler to issue a Load or Store anytime DDRA is accessed as the value may change without the compiler knowing it.

#define P0           (*(volatile __near unsigned char  *)0xFF00)
#define P0_bit       (*(volatile __near __bitf_T *)0xFF00)
#define P1           (*(volatile __near unsigned char  *)0xFF01)
#define P1_bit       (*(volatile __near __bitf_T *)0xFF01)
#define P2           (*(volatile __near unsigned char  *)0xFF02)
#define P2_bit       (*(volatile __near __bitf_T *)0xFF02)
#define P3           (*(volatile __near unsigned char  *)0xFF03)
#define P3_bit       (*(volatile __near __bitf_T *)0xFF03)
#define P4           (*(volatile __near unsigned char  *)0xFF04)
#define P4_bit       (*(volatile __near __bitf_T *)0xFF04)
#define P5           (*(volatile __near unsigned char  *)0xFF05)
#define P5_bit       (*(volatile __near __bitf_T *)0xFF05)
#define P6           (*(volatile __near unsigned char  *)0xFF06)
#define P6_bit       (*(volatile __near __bitf_T *)0xFF06)
#define P7           (*(volatile __near unsigned char  *)0xFF07)
#define P7_bit       (*(volatile __near __bitf_T *)0xFF07)
#define P12          (*(volatile __near unsigned char  *)0xFF0C)
#define P12_bit      (*(volatile __near __bitf_T *)0xFF0C)
#define P13          (*(volatile __near unsigned char  *)0xFF0D)
#define P13_bit      (*(volatile __near __bitf_T *)0xFF0D)
#define P14          (*(volatile __near unsigned char  *)0xFF0E)
#define P14_bit      (*(volatile __near __bitf_T *)0xFF0E)

C Code Support for Accessing Control Registers

The ‘iodefine.h’ file has C code constructs that make it easy to access each port with C code. Each port is defined as a structure and each register of the port is defined as a union of variables within that structure. An example of how the special function register P0 (the port register for port 0) is defined as follows.
First, a new data type called __bitf_T is defined. This allows easy C-level access to individual bits within a byte. Each field in the structure provides access to the corresponding bit. The C compiler will generate appropriate assembly code to ensure that only the bit of interest is accessed.

typedef struct
{
    unsigned char no0:1;
    unsigned char no1:1;
    unsigned char no2:1;
    unsigned char no3:1;
    unsigned char no4:1;
    unsigned char no5:1;
    unsigned char no6:1;
    unsigned char no7:1;
} __bitf_T;

你可能感兴趣的:(assign a variable name to a register address)