3
votes

PIC microcontrollers have 3 basic registers to set GPIO (General Purpose I/O) pin status. These are: TRIS (Tri-status, the direction register. Sets the pin as in or out) PORT (The input buffer) LAT (Latch, the output burffer).

Ports can be A, B, C... etc. So the TRIS register for the port A is TRISA.

Then finally there is the pin number. For example, TRISA1.

TRISA1 is defined as:

// TRISA<TRISA1>
extern volatile __bit                   TRISA1              __at(0x461);    // @ (0x8C * 8 + 1)
#define                                 TRISA1_bit          BANKMASK(TRISA), 1

I would like to define a macro to easily name the pins as:

#define _DATA_OUTPUT A2

So I can do code like:

LAT_DATA_OUTPUT = 1;
PORT_DATA_OUTPUT = 0;

and have it converted by the preprocessor to:

LATA2 = 1;
PORTA2 = 0;

so I can later expand to other pin registers such as ANSEL, WPU, etc, without rewriting the macros or add special cases.

Is this possible? Or what's the closest thing I can do to emulate this?

2
Have a look at my answer here.KamilCuk
Aren't these already defined in xc.h?cup

2 Answers

2
votes

You can do that by create macro like that:

#define _DATA_OUTPUT A2
#define LAT_DATA(X) LAT##X
#define LAT_DATA_OUTPUT    LAT_DATA(_DATA_OUTPUT)

#define PORT_DATA(X) PORT##X
#define PORT_DATA_OUTPUT PORT_DATA(_DATA_OUTPUT)

you can use it as example .

1
votes

You can already do this. You haven't noted your PIC model or your IDE version or what toolchain you are using, but assuming you're on MPLAB X with an XC compiler this functionality is already there. Make sure you're including <xc.h> and it should read what chip you have from the project configuration and have the macros already made for you.

You can then set entire registers (using TRISA as an example):

TRISA = 0x0000;    //All A pins outputs

Or set individual pins in that register:

TRISAbits.TRISA0 = 0;
TRISAbits.TRISA8 = 0;

You could also define your own macros:

#define TRISA0 TRISAbits.TRISA0
#define SET_TRISA0_IN TRISAbits.TRISA0 = 1