#define F_CPU 16000000UL
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include <stdint.h>

//pozice 1:
volatile uint8_t &portpoz1 = PORTC;
volatile uint8_t &ddrpoz1 = DDRC;
const uint8_t bitpoz1 = 3;
//pozice 2:
volatile uint8_t &portpoz2 = PORTB;
volatile uint8_t &ddrpoz2 = DDRB;
const uint8_t bitpoz2 = 1;
//displej:
volatile uint8_t &portdisplej = PORTD;
volatile uint8_t &ddrdisplej = DDRD;

inline void setbit(volatile uint8_t &reg, uint8_t bit)
{
  reg = reg | (1 << bit);
}

inline void clearbit(volatile uint8_t &reg, uint8_t bit)
{
  reg = reg & ~(1 << bit);
}

void inicializace()
{
  setbit(ddrpoz1, bitpoz1);
  setbit(ddrpoz2, bitpoz2);
  ddrdisplej = 0b11111111;

  //CTC rezim, D = 64:
  TCCR4A = 0;
  TCCR4B = (1 << WGM42) | (1 << CS41) | (1 << CS40);
  TIMSK4 = (1 << OCIE4A);  //povoleni preruseni
  OCR4A = 499;  //2 ms
}

//cislice pro zobrazeni
volatile uint8_t cislice[2] = {0, 0};

int main(void)
{
  uint8_t cislo = 12;
	
  inicializace();
  sei();  //preruseni povoleno

  while (1)
  {
    cislice[0] = cislo / 10;  //desitky
    cislice[1] = cislo % 10;  //jednotky
    cislo = (cislo + 1) % 100; //0 az 99 opakovane

    _delay_ms(100);  //prodleva
  }
}

inline void displej(uint8_t pozice, uint8_t cislice)
{
  const uint8_t dekoder[16] =
  {0b00001100, 0b00111111, 0b01000101, 0b00100101,
   0b00110110, 0b10100100, 0b10000100, 0b00111101,
   0b00000100, 0b00100100, 0b00010100, 0b10000110,
   0b11001100, 0b00000111, 0b11000100, 0b11010100};
  
  if(pozice == 0)  //pozice 1
  {
    clearbit(portpoz1, bitpoz1);
    setbit(portpoz2, bitpoz2);
  }
  else             //pozice 2
  {
    setbit(portpoz1, bitpoz1);
    clearbit(portpoz2, bitpoz2);
  }

  portdisplej = dekoder[cislice];
}

//obsluha CTC c/c 4:
ISR(TIMER4_COMPA_vect)
{
  static uint8_t pozice = 0;  //pocitadlo pozic

  //zobrazeni jedne pozice:
  displej(pozice, cislice[pozice]);
  //zmena pozice pro pristi preruseni:
  pozice = !pozice;
}