SFR Macros
If you are writing code that can be used by several devices, accessing special function registers can be problematic since the names of registers can change from one device to another or the register might not be available on all devices. Typically, programmers duplicate device-specific code and compile it conditionally, based on the particular device being used. The following example attempts to write to a port latch if one is available; otherwise, it writes directly to the corresponding port.
2
3
4
5
6
7
8
LATA = state;
#elif defined __PIC16F72
// this device does not have a latch
PORTA = state;
#else
#error compiling for unrecognised device
#endif
If you are using a recent MPLAB® XC compiler, you can alternatively compile similar code based on the presence of the actual register symbol rather than based on a device, as in:
2
3
4
5
6
7
8
LATA = state;
#elif defined PORTA
// devices that have no latch but have the port
PORTA = state;
#else
#error compiling for device with no recognised port configuration
#endif
Compiling against the register allows the code to be more versatile and target more devices, and since it is checking the actual register you are about to access, it is more reliable.
Note that some registers also have aliased symbols in the device-specific header file. These register aliases might not have macro definitions available and should not be used as shown above.