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

//vycet referencnich napeti:
enum TUref{refinterni, refexterni};
//vycet kanalu:
enum TKanal{ADC0 = 0, ADC1 = 1, ADC2 = 2, ADC3 = 3,
            ADC4 = 4, ADC5 = 5, ADC6 = 6, ADC7 = 7,
            ADTeplSenzor = 8, 
            ADInterniRef = 14,
            ADGND = 15};

inline void nastavADMUX(TUref ref, TKanal kanal)
{
  if(ref == refinterni)
    //Uref = Urefint = 1,1 V
    ADMUX = (1 << REFS1) | (1 << REFS0);
  else
    //Uref = AVCC = 5 V
    ADMUX = (1 << REFS0);
    
  ADMUX = ADMUX | kanal;
}

void inicializace()
{
  nastavADMUX(refexterni, ADInterniRef);
  //zapnuti ADC, delicka 128 (125 kHz):
  ADCSRA = (1 << ADEN) | (1 << ADPS2) | (1 << ADPS1) | (1 << ADPS0);
}

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

inline uint8_t getbit(volatile uint8_t reg, uint8_t bit)
{
  return (reg & (1 << bit)) >> bit;
}

int main(void)
{
  uint16_t uintref, teplsenzor, agnd;
  
  inicializace();
  
  while (1) 
  {
    _delay_ms(500);
    
    //mereni interniho referencniho napeti:
    nastavADMUX(refexterni, ADInterniRef);
    _delay_ms(10);
    setbit(ADCSRA, ADSC);
    while(getbit(ADCSRA, ADSC));
    uintref = ADC;
    
    //mereni analogove nuly:
    nastavADMUX(refinterni, ADGND);
    _delay_ms(10);
    setbit(ADCSRA, ADSC);
    while(getbit(ADCSRA, ADSC));
    agnd = ADC;
    
    //mereni teploty:
    nastavADMUX(refinterni, ADTeplSenzor);
    _delay_ms(10);
    setbit(ADCSRA, ADSC);
    while(getbit(ADCSRA, ADSC));
    teplsenzor = ADC;
    
    printf("Urefint = %4u, AGND = %4u, Teplotni senzor = %4u\n",
      uintref, agnd, teplsenzor);
  }
}

