Yes, it is possible to use it as a variable, but it's not as efficient as macro that generates just single bit set/clear instruction. On the other hand you can reuse the functions easily:
e.g.:
#define PIN_ON(x) *##x##.reg |= ##x##.mask
#define PIN_OFF(x) *##x##.reg &= ~##x##.mask
typedef struct {
char *reg; // poitner to the register
char mask; // bit mask
} tReg;
tReg SDA1 = {&PTADD, PTADD_PTADD0_MASK}; // define register address and particular bit(s)
tReg SDA2 = {&PTADD, PTADD_PTADD1_MASK};
void main(void)
{
PIN_ON(SDA1);
PIN_OFF(SDA1);
PIN_ON(SDA2);
PIN_OFF(SDA2);
}Disassembly listing:
21: PIN_ON(SDA1);
0001 c60002 [4] LDA SDA1:2
0004 320000 [5] LDHX SDA1
0007 fa [3] ORA ,X
0008 f7 [2] STA ,X
22: PIN_OFF(SDA1);
0009 c60002 [4] LDA SDA1:2
000c 43 [1] COMA
000d 320000 [5] LDHX SDA1
0010 f4 [3] AND ,X
0011 f7 [2] STA ,X
23:
24: PIN_ON(SDA2);
0012 c60002 [4] LDA SDA2:2
0015 320000 [5] LDHX SDA2
0018 fa [3] ORA ,X
0019 f7 [2] STA ,X
25: PIN_OFF(SDA2);
001a c60002 [4] LDA SDA2:2
001d 43 [1] COMA
001e 320000 [5] LDHX SDA2
0021 f4 [3] AND ,X
0022 f7 [2] STA ,X
Using register macros will generate more efficient code:
void main(void)
{
PTADD_PTADD0 = 1;
PTADD_PTADD0 = 0;
PTADD_PTADD1 = 1;
PTADD_PTADD1 = 0;
}Disassembly listing:
27: PTADD_PTADD0 = 1;
0001 1000 [5] BSET 0,_PTADD
28: PTADD_PTADD0 = 0;
0003 1100 [5] BCLR 0,_PTADD
29:
30: PTADD_PTADD1 = 1;
0005 1200 [5] BSET 1,_PTADD
31: PTADD_PTADD1 = 0;
0007 1300 [5] BCLR 1,_PTADD
Stanish