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-cc
-mcpu=16f1946 -mdfp="Microchip/PIC12-16F1xxx_DFP/1.7.242/xc8" -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>
.