3.3.2.5 How Do I Find The Names Used To Represent SFRs And Bits?
Special function registers (SFRs), as well as the bits within them, are accessed in C code via special variables that map over the register. In assembly code, SFRs are referenced using preprocessor macros and other symbols equated to the address of the registers. In both cases, however, the names of these variables or symbols sometimes differ from those indicated in the data sheet for the device you are using. There are several ways you can determine the exact names to use.
<xc.h>
header file you include in your C source code will include other device-specific header files that are relevant for your device and build configuration. These device-specific headers (located in the pic/include/proc directory of your compiler distribution) will contain definitions and preprocessor macros that provide access to the special C variables that map over the SFRs. The following extract from the pic16f1946.h header shows the unsigned char
variable WPUG
that maps over the entire WPUG register. Additionally, it shows the structure definition called WPUGbits
, which allows C-based access to the WPUG5 bit within that register, as well as the __bit
definition of the same bit. Preprocessor macros, such as _WPUG_WPUG5_POSN
provide information about the size and position of bits within the register should you need to perform bit operations on this SFR.#define WPUG WPUG
extern volatile unsigned char WPUG __at(0x48D);
typedef union {
struct {
unsigned :5;
unsigned WPUG5 :1;
};
} WPUGbits_t;
extern volatile WPUGbits_t WPUGbits __at(0x48D);
extern volatile __bit WPUG5 __at(0x246D);
#define _WPUG_WPUG5_POSN 0x5
#define _WPUG_WPUG5_POSITION 0x5
#define _WPUG_WPUG5_SIZE 0x1
#define _WPUG_WPUG5_LENGTH 0x1
#define _WPUG_WPUG5_MASK 0x20
C code using these might look like the following.#include <xc.h>
#ifdef WPUG
WPUG = 0; // access register as a whole
WPUGbits.WPUG5 = 1; // access bits within register structure
WPUG5 = 1; // access bit objects with register
#endif
.h
headers also provide definitions and macros for assembly code placed in-line with C code. Look for equate directives (EQU
) and macros using the _BIT_ACCESS()
macro. In the following header extract, the entire register is represented by the symbol WPUG
, and the byte/bit offset combination, WPUG5_bit
, usable as the operand to bit-orientated file register instructions.asm("WPUG equ 048Dh");
#define WPUG5_bit _BIT_ACCESS(WPUG,5)
These might be used in C code as follows:#include <xc.h>
void process(void) {
__asm("BANKSEL WPUG");
__asm("clrf " ___mkstr(BANKMASK(WPUG)));
__asm(" bsf " WPUG5_bit);
}
.inc
extension are also located in the same compiler directory and contain preprocessor macros and other SFR symbols to be used for hand-written assembly code contained in a separate module. The following extract from the pic16f1946.inc header shows the WPUG
symbol equated to its address, as well as the macro WPUG5
, which can be used as the operand to many assembly instructions to represent bit #5 in the WPUG register.#define WPUG WPUG
WPUG equ 048Dh
#define WPUG5 BANKMASK(WPUG), 5
WPUG_WPUG5_POSN equ 0005h
WPUG_WPUG5_POSITION equ 0005h
WPUG_WPUG5_SIZE equ 0001h
WPUG_WPUG5_LENGTH equ 0001h
WPUG_WPUG5_MASK equ 0020h
These might be used in assembly code as follows.#include <xc.inc>
psect code
BANKSEL(WPUG)
clrf BANKMASK(WPUG)
bsf WPUG5
movlw WPUG_WPUG5_MASK
andwf BANKMASK(WPUG)
Rather than find and inspect the relevant device-specific header, you can look for the above variables in the preprocessed output of any C file that includes the <xc.h>
header. This can be a more reliable approach, as preprocessed files will only contain information relevant for your build configuration. If you want to perform this preprocessing step explicitly, you can use the -E
option, which will have the compiler preprocess the source files and then halt compilation. If you are compiling under MPLAB X IDE for a configuration called default
, the preprocessed file(s) are left in the build/default/production directory of your project for regular builds, or under build/default/debug for debug builds. Preprocessed files have a .i extension.
-E
and -dM
options on the command line. For example, if blankfile.c included <xc.h>
, then the command:xc8 -mcpu=16f1939 -E -dM blankfile.c
will show output such as:...
#define WPUG5_bit _BIT_ACCESS(WPUG,5)
#define _WPUG_WPUG5_LENGTH 0x1
#define _WPUG_WPUG5_MASK 0x20
#define _WPUG_WPUG5_POSITION 0x5
#define _WPUG_WPUG5_POSN 0x5
#define _WPUG_WPUG5_SIZE 0x1
...
The -E
and -dM
options can also be used to see the names of macros when building any assembly source file that includes <xc.inc>
.