You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

120 lines
2.2 KiB
C

#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/sleep.h>
#include <avr/eeprom.h>
#define ACTIVE_TIME 1 // minutes
#define ANIMATION_INTERVALL 3 // counter increments (0.016 sec)
uint8_t EEMEM on_off_state;
volatile uint32_t leds = 0x00;
uint8_t anim_nr = 0;
void random(void);
void links_rechts(void);
void (*animation[])(void) = {
links_rechts,
random
};
unsigned long NextVal(void)
{
static unsigned long Seed;
Seed=Seed*1632125L+1013904223L;
return Seed;
}
void random(){
int temp;
do{
temp=NextVal();
temp=1 << (temp%18);
}while(temp==leds);
leds=temp;
}
void links_rechts(){
static uint8_t dir = 0;
if(dir)
leds = leds << 1;
else
leds = leds >> 1;
if(!(leds & 0x1FFFF)){
leds = 0x08;
dir^=1;
}
}
void write_leds(void){
PORTD = leds & 0xFF;
PORTC = (leds>>8) & 0x3F;
PORTB = (leds>>14) & 0x07;
}
int main(void)
{
// reset switch as on/off switch
if(eeprom_read_byte(&on_off_state)){
eeprom_write_byte(&on_off_state, 0);
}
else{
eeprom_write_byte(&on_off_state, 1);
set_sleep_mode(SLEEP_MODE_PWR_SAVE);
sleep_mode();
// power consumption is below 1uA
}
DDRC = 0xFF;
DDRD = 0xFF;
DDRB = 0x07;
TCCR0B |= (1<<CS01)|(1<<CS00);
TIMSK0 |= 1 << TOIE0;
ADCSRA |= (1<<ADEN) | (1<<ADPS1) | (1<<ADPS0);
ADMUX = 1<<REFS0;
ADMUX |= 6;
sei();
while(1)
{
write_leds();
//check buttons on ADC6 and ADC7
ADCSRA |= 1<<ADSC;
while(ADCSRA & (1<<ADSC));
if(ADC < 512){
if(ADMUX & 0x01)
anim_nr = 0;
else
anim_nr = 1;
anim_nr%=sizeof(animation);
}
ADMUX ^= 0x01;
}
}
ISR(TIMER0_OVF_vect){
static uint32_t active_count = 0;
static uint16_t count = 0;
active_count++;
if(count>=ANIMATION_INTERVALL){
count=0;
(*animation[anim_nr])();
}
else
{
count++;
}
if(active_count >= ACTIVE_TIME * 3662){
leds=0;
write_leds();
eeprom_write_byte(&on_off_state, 1);
set_sleep_mode(SLEEP_MODE_PWR_SAVE);
sleep_mode();
}
}