How to #define multiple ports/pins together

Thread Starter

Vaughanabe13

Joined May 4, 2009
102
Let me preface by saying I am working with a Microchip PIC32MX-series chip and the C32 compiler.
Ok so usually when I want to define a port pin as some name, I do it like this

Rich (BB code):
#define LED        PORTCbits.RC0
And if I want to #define an entire port, I do it like this:

Rich (BB code):
#define BUS_B        PORTB
In this case, BUS_B represents 16 bits, since PORTB is 16 bits wide on my device.

Now my question is, how do I define "BUS_B" such that it includes PORTB and another port concatenated together? So I want PORTB to represent the least significant bits of BUS_B, and lets say PORTF as the most significant bits of BUS_B with RF6 as the most significant bit of BUS_B. On my device PORTF is 7-bits wide, so I essentially want to declare BUS_B as a (7+16)-bit 'chunk' where PORTF and PORTB are concatenated together. So then when I want to output data to BUS_B, I just assign a 23-bit value to BUS_B, like so:

Rich (BB code):
BUS_B = 0x7FFFFF;   //(23 bits of all 1's)
So I want the most significant bits of that 0x7FFFFF to be assigned to PORTF and the rest assigned to PORTB. So what do I assign to the right of "#define BUS_B" so that it does what I am asking? Hopefully I am clear in my meaning.
 

Thread Starter

Vaughanabe13

Joined May 4, 2009
102
Hmmm, I don't think that would work. You seem to be masking off the upper 8 bits of PORTB and since PORTF is only 7 bits you are masking off all of PORTF.

I'm intrigued with the or operation though. What is your intent with that?
 

DonQ

Joined May 6, 2009
321
It may be debatable about if this will do what you want on the right hand side of the equals sign, it will certainly not do what you want on the left hand side of the equals sign.

You can see this by expanding the defines:

if :
#define BUS_B1 PORTB&0b000000011111111
#define BUS_B2 PORTF&0b111111100000000
#define BUS_B BUS_B1|BUS_B2

BUS_B = value;

expands to:

PORTB&0b000000011111111 | PORTF&0b111111100000000 = value;

I guarantee that any compiler will complain about this! (ERROR: L value required, or similar, meaning that the expression on the Left can not be assigned to).

Since you are actually using pointers to addresses, you will not be able to combine these values directly, you would have to at least go through some crazy pointer structures/unions/typecasts to get what you want.

Probably easier to just make get/put subroutines that input/outputs the parts of the values you want to/from the required ports.
 
Try using a #define with parameters, like:

#define SET_BUS_B(value) ....

then, in the definition, you set BUS_B1 and BUS_B2 using & and >> operators as needed, separated by either a ; or ,

When I do #defines with multiple statements, I enclose them in curly braces {} so that it comes out as a single statement even when it's the sole thing in a loop or conditional.
 

Thread Starter

Vaughanabe13

Joined May 4, 2009
102
I'm doing it as a macro right now and it seems to work well. The code is below. Thanks for the help.

Rich (BB code):
#define VB_ADDRESS_BUS(p)        { PORTD = (p); PORTE = (p)>>12; _RF2 = (p)>>20; _RF3 = (p)>>21; _RF4 = (p)>>22; }
 
Top