// ATMega 8
// ADC példaprogram

#include <util/delay.h>
#include <avr/io.h>

#define LEDon	PORTD |= (1<<PIND7)
#define LEDoff  PORTD &= ~(1<<PIND7)

volatile int adc=0; 


// IO portok beállítása
void InitPORT() {

//           6543210
    DDRC = 0b1011111;
//  PC5-ADC5 bemenet, többi kimenet
    
    DDRB = 0xFF;

//           76543210 
    DDRD = 0b10000000;
//  PD7 kimenet(LED), többi bemenet
    PORTD=0x00;
}

// ADC beállítása
//--------------------------------------------
void InitADC() {

//********************************************
//            76543210
    ADMUX = 0b01000000;
//********************************************
//    7  REFS1
//    6  REFS0
//       00 - Referencia az AREF láb, belső referencia lekapcsolva.
//       01 - Referencia az AVCC láb, AREF láb kondenzátorral testre kötve.
//       10 - Foglalt
//       11 - Belső 2.56 Voltos referencia, AREF láb kondenzátorral testre kötve.
//--------------------------------------------
//    5  ADLAR
//--------------------------------------------
//    4  nem használt
//--------------------------------------------
//    3  MUX3
//    2  MUX2
//    1  MUX1
//    0  MUX0
//       ADC port választás binálisan megadva. Itt érdemes 0000 értéket megadni,
//       mert lekérdezéskor állítjuk be a portot.

//********************************************
//             76543210
    ADCSRA = 0b10000111;
//********************************************
//    7  ADEN
//       ADC engedélyezve ha értéke 1, kikapcsolva ha 0.
//--------------------------------------------
//    6  ADSC
//       Egyszeri mérésnél 1-re kell állítani, hogy megtörténjen a mérés.
//       Folyamatos mérésné ha 1-re állítjuk elindul a mérés,
//       ami utánna folyamatosan fut.
//--------------------------------------------
//    5  ADFR
//       Ha 1 akkor folyamatos mérés fut, ha 0 akkor egyszeri.
//--------------------------------------------
//    4  ADIF
//       Interrupt Flag - nem kell piszkálni :)
//       Ha 1 akkor a megszakítás jött létre.
//--------------------------------------------
//    3  ADIE
//       Ha 1 akkor a mérés végén megszakítás jön létre.
//       Ha 0 akkor a megszakítás kikapcsolva.
//--------------------------------------------
//    2  ADSP2
//    1  ADSP1
//    0  ADSP0
//       Előosztás
//       000 - 1
//       001 - 2
//       010 - 4
//       011 - 8
//       100 - 16
//       101 - 32
//       110 - 64
//       111 - 128

} // InitADC


//--------------------------------------------
uint16_t ReadADC(uint8_t ch) {

    ADMUX = (ADMUX & 0b11110000) | ch;
//              példa ha ADC 5-ös portot olvasunk. ch értéke (5) binárisan (00000101)
//  01000001    ADMUX jelenlegi állapota (1-es ADC csatorna beállítva)
//& 11110000    ezzel töröljük az előző portk kiválasztást
//= 01000000    eredménynek kapjuk az eredeti ADMUX beállítást
//| 00000101    "ráírjuk" az ADC csatornát
//= 01000101    

    ADCSRA|=(1<<ADSC);          // konverzió elindítás

    while(ADCSRA & (1<<ADSC));  // várás az átalakításra

    return (ADCL | (ADCH<<8));  // adc érték visszaadása

} // ReadADC

//--------------------------------------------
int main() {

    InitPORT(); // portok beállításai lefuttatása
    InitADC();  // ADC beállítás lefuttatása

    for (;;) {

        adc = ReadADC(5);
//      adc változóva írjuk az aktuális ADC értéket.
//      az érték egy 0-1023 közötti szám

//      ezzel az értékkel már bármit csinálhatunk,
//      most bekapcsolunk egy ledet, ha ADC nagyobb mint 500
        if(adc > 500)   {LEDon;}
        else            {LEDoff;}     

        _delay_ms(100);
        
    } // for
} // main

