Comprendo ahora que estas intentando hacer.. Pero para lo que vos buscas hacer es mejor usar una union.
Cada compilador tiene su forma que no es estandar ni pertenece a C de definir algunas cosas, como es el caso de los registros en XC8 y luego tenemos XC16 que es mas parecido a gcc. Voy a copiar de forma completa la definicion de un puerto en XC8, el de XC16 ya lo pasaste, asi que lo voy a explicar nomas.
XC8:
// Register: PORTC
#define PORTC PORTC
extern volatile unsigned char PORTC @ 0x007;
#ifndef _LIB_BUILD
asm("PORTC equ 07h");
#endif
// bitfield definitions
typedef union {
struct {
unsigned RC0 :1;
unsigned RC1 :1;
unsigned RC2 :1;
unsigned RC3 :1;
unsigned RC4 :1;
unsigned RC5 :1;
unsigned RC6 :1;
unsigned RC7 :1;
};
} PORTCbits_t;
extern volatile PORTCbits_t PORTCbits @ 0x007;
De aca tenes que observar 2 cosas.... el @ 0x007, que es la direccion de memoria que ocupa el registro PORTC.
Y la otra es que se definen 2 cosas en la misma direccion , uno que es el PORTC, y otro que es la estructura que es PORTCbits, por eso acceden a lo mismo.
En cambio XC16 pertenece o es un GCC modificado por Microchip.. El cual podes hacer uso de los atributos:
https://gcc.gnu.org/onlinedocs/gcc-3.2/gcc/Function-Attributes.htmlObservaras en la lista que no existe ningun atributo __sfr__ , y que es especial de Microchip.
Esto hace muy parecido a lo visto con XC8 y lo maneja de forma interna el compilador (realizado unicamente para sus registros). Por eso lo que planteas no funcionaria....
-----------------------------------
Si podes hacerlo con una union, ejemplo:
typedef union BANDERA_t {
uint16_t completo;
struct bits_s {
uint16_t bandera:15;
uint16_t tecla:1;} bits;
} BANDERA_t;
En tu main:
BANDERA_t BANDERAS;
while(1){
BANDERAS.completo = 0x0AA0; // Con esto accedo a los 16 bits
BANDERAS.bits.tecla = 1; // Con esto accedo a la parte de 1 bit
BANDERAS.bits.bandera = 12; // Con esto accedo a los demas 15 bits
}
Tanto el completo como los bits, ocupan una sola posicion de memoria. El unico problema de los bitfields, es que es de implementacion especifica de cada compilador el orden de los mismos. Por ejemplo, en la simulacion puedo observar que el bit de tecla es el de mayor peso. Pero que en otro compilador (por si deseas usar el mismo codigo en otro lado) podria no ser asi. Asi que necesitas tener eso en cuenta.
Si te preguntas , uint16_t significa entero sin signo de 16 bits y esta definido en stdint.h el cual necesitas agregar si queres usar esas definiciones, sino reemplazalo por tu unsigned int.