I'm programming the Atmega328P in embedded C. I'm going to use 16 pins for turning on LEDs, and I have to use PORTB, PORTD and PORTC for this. I would like to just iterate a pointer so I can turn them on/off instead having to deal with what port each pin relates to. So an example would be how I need three if statements to iterate through the 16 pins like shown below:
// Enable outputs
DDRB = 0b00111111; // 6 outputs
DDRC = 0b00110000; // 2 outputs
DDRD = 0xFF; // 8 outputs
// LED pins
uint8_t ledpin[] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
uint8_t idx = 0;
// Set LEDs
if (idx < 8)
for(int i = 0; i < 8; i++)
PORTD |= (1 << ledpin[i]);
if( idx > 8 && idx < 14)
for(int i = 8; i < 14 ; i++)
PORTB |= (1 << ledpin[i]);
if (idx >= 14)
for(int i = 14; i < 16; i++)
PORTC |= (1 << ledpin[i]);
I would rather use a memory map where I could just say "pin0 address + offset" like this:
// Base address of ports
uint8_t base 0x00
uint8_t offset = 0x04;
// LED pins
uint8_t ledpin[] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
// Set LEDs
for(int i = 0; i < 16; i++){
(base + offset) |= (1 << ledpin[i]); // Pseudo code
offset += 0x04;
}
The code above is obviously not optimized, nor totally functioning code but I think it gets my point accross as to what I want to achieve. Ultimately I will use this in a code to control a LED cube which will work quite differently, but it's essential that I don't need to decode what port each pin belong to all the time. Is there a good way to solve this with virtually no overhead?
EDIT
After investigating and trying out a lot of stuff with good help from the answers I have found that it's not possible to address individual bits in the AVR ports. Each PORTB/C/D have their own address, but it's not possible to manipulate the bits with memory mapping, like incrementing a pointer address. Atmega328P datasheet page 280 shows the memory map of the IO ports (image below).
offset()
to return? Your original code is changing a single bit at a time using the OR operator but your pseudocode doesn't have the OR operator...I don't get it. \$\endgroup\$for
statement in the last but one line, probably unintentionally. \$\endgroup\$