avr-chat
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [avr-chat] Array access to ports


From: David Brown
Subject: Re: [avr-chat] Array access to ports
Date: Mon, 29 Oct 2007 09:25:27 +0100
User-agent: Thunderbird 2.0.0.6 (Windows/20070728)

Ron Kreymborg wrote:
I am addressing a dozen or so LEDs on a number of different ports, turning
them on and off. I would like to address them through an array structure
that stores the relevant port and mask. For example:

typedef enum
{
    T_LED_OFF,
    T_LED_ON
} LED_STATE_TYPE;

typedef struct
{
    MYPORT    port;
    uint8     mask;
} LED_TYPE;

I could designate the respective LEDs with names. For example:

typedef enum
{
   LEDOUT,
   etc
} LED;

I had hoped to be able to preload the array something like:

static LED_TYPE LedList[] = {
    {PORTB, 0x20},                // LEDOUT
    {etc}
};

Where the 0x20 is the mask for pin5 of PORTB for the LEDOUT led. I could
then use a simple function to address all leds. For example, turning the
LEDOUT led on (high) would look like:

   ChangeLedState(LEDOUT, T_LED_ON);

And the partial function:

void ChangeLedState(LED index, LED_STATE_TYPE state)
{
   if (state == T_LED_ON)
      LedList[index].port |= LedList[index].mask;
   .
   .

The snag of course is that PORTB is not a constant but an SFR. Can anyone
suggest whether assigning a port like this is possible, and what would be
the definition of MYPORT?

Cheers
Ron


You can't store an array of SFR's like this - but you can store an array of pointers to them:

typedef volatile uint8_t vuint8_t;
typedef vuint8_t pvuint8_t;

typedef struct { pvuint8_t pPort; uint8_t mask; } ledType;

static ledType ledList[] = { { &PORTB, 0x20 }, { &PORTC, 0x10 } };

Then you can write:
        *(ledList[index].pPort) |= ledList[index].mask;


Of course, the run-time overhead for this sort of thing is quite significant, especially if your code almost always uses compile-time constants (i.e., your "ChangeLedState" function is always called with fixed values). You can avoid that by making your ChangeLedState function inline (possibly with the "always_inline" attribute), so that the compiler handles the lookups at compile-time, and gives you a single sbi or cbi instruction.

mvh.,

David





reply via email to

[Prev in Thread] Current Thread [Next in Thread]