How to #define multiple ports/pins together

Discussion in 'Embedded Systems and Microcontrollers' started by Vaughanabe13, Aug 26, 2010.

  1. Vaughanabe13

    Thread Starter Active Member

    May 4, 2009
    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

    Code ( (Unknown Language)):
    1. #define LED        PORTCbits.RC0
    And if I want to #define an entire port, I do it like this:

    Code ( (Unknown Language)):
    1. #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:

    Code ( (Unknown Language)):
    1. 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.
  2. vantusaonho

    New Member

    Apr 28, 2010
    Try this code
    Code ( (Unknown Language)):
    1. #define BUS_B1        PORTB&0b000000011111111
    2. #define BUS_B2        PORTF&0b111111100000000
    3. #define BUS_B         BUS_B1|BUS_B2
  3. Vaughanabe13

    Thread Starter Active Member

    May 4, 2009
    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?
  4. DonQ

    Active Member

    May 6, 2009
    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.
  5. sage.radachowsky


    May 11, 2010
    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.
  6. Vaughanabe13

    Thread Starter Active Member

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

    Code ( (Unknown Language)):
    2. #define VB_ADDRESS_BUS(p)        { PORTD = (p); PORTE = (p)>>12; _RF2 = (p)>>20; _RF3 = (p)>>21; _RF4 = (p)>>22; }