Skip to content

Instantly share code, notes, and snippets.

@deoxxa
Created May 7, 2014 11:03
Show Gist options
  • Save deoxxa/78f89a7bbdc9d83d71ed to your computer and use it in GitHub Desktop.
Save deoxxa/78f89a7bbdc9d83d71ed to your computer and use it in GitHub Desktop.
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/power.h>
#include <avr/sleep.h>
volatile unsigned char count = 0; // should overflow to 0
void write_leds(unsigned char value) {
int i;
for (i=0;i<8;++i) {
// set data line
if ((value & (1 << i)) != 0) {
PORTB |= _BV(PORTB2);
} else {
PORTB &= ~(_BV(PORTB2));
}
// pulse clock (maybe a delay would be good? works without it anyway)
PORTB |= _BV(PORTB3);
PORTB &= ~(_BV(PORTB3));
}
}
void read_buttons() {
// top button
if (bit_is_set(PIND, PIND2) == 0) {
PORTB ^= _BV(PORTB0);
// middle button
} else if (bit_is_set(PIND, PIND3) == 0) {
PORTB ^= _BV(PORTB1);
// bottom button
} else if (bit_is_set(PIND, PIND4) == 0) {
PORTB &= ~(_BV(PORTB0) | _BV(PORTB1));
// button release, early exit
} else {
return;
}
write_leds(++count);
}
ISR(PCINT2_vect) {
read_buttons();
}
int main (void) {
// configure pins 0, 1 and 5 of upper port for output
// 0 and 1 are led's
// 2 and 3 are input and clock of a shift register
// 5 is the status led onboard
DDRB |= _BV(DDB0);
DDRB |= _BV(DDB1);
DDRB |= _BV(DDB2);
DDRB |= _BV(DDB3);
DDRB |= _BV(DDB5);
// activate pull-up circuits for buttons
PORTD |= _BV(PORTD2);
PORTD |= _BV(PORTD3);
PORTD |= _BV(PORTD4);
// activate pin change interrupt 2
PCICR |= _BV(PCIE2);
// activate interrupt for pins 18, 19 and 20 (buttons)
PCMSK2 |= _BV(PCINT18);
PCMSK2 |= _BV(PCINT19);
PCMSK2 |= _BV(PCINT20);
sei();
write_leds(count);
do {
set_sleep_mode(SLEEP_MODE_IDLE);
sleep_enable();
PORTB &= ~(_BV(PORTB5));
sleep_mode();
sleep_disable();
PORTB |= _BV(PORTB5);
} while (1);
cli();
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment