0

Due to design limitations, I have an address line for a memory controller split across 3 different ports of a PIC 18F4550. Mapping:

#define A0 PORTBbits.RB2
#define A1 PORTBbits.RB3
#define A2 PORTBbits.RB4
#define A3 PORTBbits.RB5
#define A4 PORTAbits.RA0
#define A5 PORTAbits.RÄ1
#define A6 PORTAbits.RÄ2
#define A7 PORTAbits.RÄ3
#define A8 PORTAbits.RÄ4
#define A9 PORTAbits.RÄ5
#define A10 PORTEbits.RE0
#define A11 PORTEbits.RE1
#define A12 PORTEbits.RE2

I would like to access this as one single variable ADDRESS, and have tried using a union to do it, but simply get a 'Syntax error' with:

union
{
        struct
        {
            A0 :1;
            A1 :1;
            A2 :1;
            A3 :1;
            A4 :1;
            A5 :1;
            A6 :1;
            A7 :1;
            A8 :1;
            A9 :1;
            A10 :1;
            A11 :1;
            A12 :1;
        };
} ADDRESS;

How do I go about doing this?

Ali Lown
  • 2,323
  • 1
  • 18
  • 22
  • No, that is never going to work - you can't use a union to do this. Whatever solution you come up with I'm afraid it's going to be ugly. You'll probably need one or more macros or functions to convert between addresses and the various port bits. – Paul R Mar 31 '11 at 21:55
  • Ok, so as I suspected, some bit-shifting and masking will be needed. I will have a go tomorrow and post a response. – Ali Lown Mar 31 '11 at 22:01

1 Answers1

0

This won't be really easy has the I/O your are using are hashed into several ports.

The only simplification you can do is to manage your memory into pages accessed by three different address chunks:

lowAddr will be RB2:RB5
midAddr will be RA0:RA5
highAdd will be RE0:RE2

It would have been preferable to have the bigger chunk for low address part so the memory pages can be larger. Here you will have only 16 bytes pages.

Hence you can define a bit-field structure to manage your memory into a single variable.

struct {
   uint16 lowAddr : 4;
   uint16 midAddr : 6;
   uint16 highAddr : 3;
   uint16 : 3;
} memoryAddr;

This way you can handle more efficiently the port updating like for portB:

LATB &= 0xFF ^ (3 << 2);
LATB |= memoryAddr.lowAddr << 2;
greydet
  • 5,509
  • 3
  • 31
  • 51
  • I normally write directly to PORTB, what advantage is there to using the LATB registers instead? – Ali Lown Apr 01 '11 at 15:47
  • @Ali you will find a good answer to this question on the following link: http://stackoverflow.com/questions/2623428/difference-between-port-and-latch-on-pic-18f – greydet Apr 01 '11 at 20:09