// Multiplex7seg V 1.0 (c) Oliver Mezger 9.1.2010
#include <avr/io.h>     // Definitionen laden
#include <util/delay.h> // Delay-Bibliothek laden
#include <avr/interrupt.h>

// Zuordnungen zu Ports
#define SegmentIn   PINA
#define SegmentOut  PORTA
#define SegmentDdr  DDRA
#define TastaturIn  PINB
#define TastaturOut PORTB
#define TastaturDdr DDRB
#define StelleIn   PINC
#define StelleOut  PORTC
#define StelleDdr  DDRC

const unsigned char bcd_7[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
volatile unsigned char anzeige[4]={0,0,0,0};

ISR(TIMER0_OVF_vect){
  static unsigned char spalte=1,dzeiger=0;
  TCNT0=150;
  SegmentOut = bcd_7[anzeige[dzeiger++]]; // Segmentmuster ausgeben
  StelleOut = (StelleOut & 0b11100000) | spalte; // Stelle einschalten
  spalte *= 2;  // naechste Spalte
  if (dzeiger >3){
    spalte = 1;
    dzeiger = 0;
  }
}

void zaehle(){  // erhoehe Zaehler um 1
  unsigned char i;
  anzeige[0]++;
  for(i=0;i<3;i++){
    if (anzeige[i] > 9){
      anzeige[i]=0;
      anzeige[i+1]++;
    }
  }
}
int main(){
  unsigned char led =0;
  TCCR0 = 3;    // Systemtakt / 64
  TIMSK |= (1<<TOIE0); // Timerinterrupt frei geben
  SegmentDdr=0xff;  // Ausgang
  StelleDdr=0xff;  // Ausgang
  TastaturOut = 0b11101111;
  TastaturDdr = 0b00010000;
  sei();        // globale Interruptfreigabe
  while(1){     // Endlosschleife
    if ((TastaturIn & 1) ==0){
      while((TastaturIn & 1) ==0);
      zaehle();
    }
    led++;
    led &= 7;
    StelleOut = (StelleOut & 0b00011111) | (led<<5);
    _delay_ms(100); // warte 100ms
  }
  return 0;
}
