I'm trying to map some locations, and here is a sample of my code. The point I want to declare porta and ddra as an extern variables so I can share them between files.
typedef union _porta
{
byte REGISTER;
struct
{
unsigned PA0:1;
unsigned PA1:1;
unsigned PA2:1;
unsigned PA3:1;
unsigned PA4:1;
unsigned PA5:1;
unsigned PA6:1;
unsigned PA7:1;
};
}PORTA;
typedef union _da
{
byte REGISTER;
struct
{
unsigned DA0:1;
unsigned DA1:1;
unsigned DA2:1;
unsigned DA3:1;
unsigned DA4:1;
unsigned DA5:1;
unsigned DA6:1;
unsigned DA7:1;
};
}DDRA;
#define porta (*(( volatile PORTA *)0x22))
#define ddra ( *(( volatile DDRA *)0x21) )
// Here in the same header want to declare porta and ddra as an extern variables I can use outside
Simple put the defines and the typedefs in a header file and name it "xxx_registers.h" or some such (where xxx is your MCU). That's how this is usually done.
However, you should name the typedef DDRA_t
and then #define DDRA ... volatile DDRA_t*
. It is custom to always use capital letters for register names.
IMPORTANT: Make sure that strict aliasing is disabled in your compiler! Otherwise code like this may break in horrible ways. This is mostly a problem with the gcc compiler, but other compilers might handle strict aliasing in similar dysfunctional ways. For gcc, always compile with -fno-strict-aliasing
when coding embedded systems, or otherwise that compiler can't be used.
Please note that bit-fields are non-portable and dangerous, so there is no guarantee that this code will work on other compilers. It is better and safer to use bitwise operators for accessing individual bits, rather than bit-fields.