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
_______________________________________________
AVR-chat mailing list
[email protected]
http://lists.nongnu.org/mailman/listinfo/avr-chat