SFR Macros

Last modified by Microchip on 2024/02/06 09:29

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.

1
2
3
4
5
6
7
8
#if defined __PIC16F1847
   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:

1
2
3
4
5
6
7
8
#if defined LATA
   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.