/*
Sketch uses 354 bytes (1%) of program storage space. Maximum is 32256 bytes.
Global variables use 0 bytes (0%) of dynamic memory, leaving 2048 bytes for local variables. Maximum is 2048 bytes.
FUNCTION: void set_led()
Step 1 resets all 3 pins to input.
Step 2 clears the PORTD bits, which disables any internal pull-up resistors.
Step 3 re-enables only the two needed output pins.
Step 4 sets HIGH/LOW levels.
*/
#define F_CPU 16000000UL
#include <avr/io.h>
#include <util/delay.h>
// Define bit positions
#define PIN_A PD2
#define PIN_B PD3
#define PIN_C PD4
void setup() {
// Initially set all pins as input
//DDRD &= ~(1 << PIN_A) & ~(1 << PIN_B) & ~(1 << PIN_C);
//DDRD = 0x00;
DDRD &= ~((1 << PIN_A) | (1 << PIN_B) | (1 << PIN_C));
}
void set_led(uint8_t high, uint8_t low, uint8_t z) {
// Step 1: Set all pins as input first
// This works to set DDRD as 0, but not best practice
DDRD &= ~(1 << PIN_A) & ~(1 << PIN_B) & ~(1 << PIN_C);
// This works to set DDRD as 0, but clears all of DDRB, be careful!
DDRD = 0x00;
// This works to set DDRD as 0, !! best practice method !!
DDRD &= ~((1 << PIN_A) | (1 << PIN_B) | (1 << PIN_C));
// Step 2: Disable pull-ups (ensure Hi-Z) on all three
PORTD &= ~((1 << PIN_A) | (1 << PIN_B) | (1 << PIN_C));
// Step 3: Set high and low pins as output
DDRD |= (1 << high) | (1 << low);
// Step 4: Drive the pins
PORTD |= (1 << high); // High
PORTD &= ~(1 << low); // Low
}
int main(void) {
setup();
while(1) {
set_led(PIN_A, PIN_B, PIN_C); // LED1: A -> B
_delay_ms(500);
set_led(PIN_B, PIN_A, PIN_C); // LED2: B -> A
_delay_ms(500);
set_led(PIN_A, PIN_C, PIN_B); // LED3: A -> C
_delay_ms(500);
set_led(PIN_C, PIN_A, PIN_B); // LED4: C -> A
_delay_ms(500);
set_led(PIN_B, PIN_C, PIN_A); // LED5: B -> C
_delay_ms(500);
set_led(PIN_C, PIN_B, PIN_A); // LED6: C -> B
_delay_ms(500);
}
}