├── readme.txt ├── circuit for all 4 ADC examples.png ├── ADC_FreeRunning.c ├── ADC_WithInterruptFreeRunning.c ├── ADC_SingleConversion.c └── ADC_WithInterruptSingleConversion.c /readme.txt: -------------------------------------------------------------------------------- 1 | The video pretty much explains it all: 2 | https://www.youtube.com/watch?v=9qxCA8YfAN4 -------------------------------------------------------------------------------- /circuit for all 4 ADC examples.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrocontrollersAndMore/Atmel_Programming_Tutorial_4_Analog_Inputs/HEAD/circuit for all 4 ADC examples.png -------------------------------------------------------------------------------- /ADC_FreeRunning.c: -------------------------------------------------------------------------------- 1 | // ADC_FreeRunning.c 2 | 3 | // 10k ohm pot on PC5/ADC5 (pin 28) 4 | // 8 LEDs on Port D pins 5 | 6 | #ifndef F_CPU // if F_CPU was not defined in Project -> Properties 7 | #define F_CPU 1000000UL // define it now as 1 GHz unsigned long 8 | #endif 9 | 10 | #include // this is always included in AVR programs 11 | 12 | /////////////////////////////////////////////////////////////////////////////////////////////////// 13 | int main(void) { 14 | 15 | DDRD = 0xFF; // set Port D pins for output 16 | 17 | /* 18 | ADMUX - ADC Multiplexer Selection Register 19 | 20 | bit 7 6 5 4 3 2 1 0 21 | name REFS1 REFS0 ADLAR - MUX3 MUX2 MUX1 MUX0 22 | set to 0 1 1 0 0 1 0 1 23 | 24 | REFS1 = 0 use AVCC for reference voltage 25 | REFS0 = 1 26 | 27 | ADLAR = 1 left justify ADC result in ADCH/ADCL 28 | 29 | bit 4 = 0 30 | 31 | MUX3 = 0 use PC5/ADC5 (pin 28) for input 32 | MUX2 = 1 33 | MUX1 = 0 34 | MUX0 = 1 35 | */ 36 | ADMUX = 0b01100101; 37 | 38 | /* 39 | ADCSRA - ADC Control and Status Register A 40 | 41 | bit 7 6 5 4 3 2 1 0 42 | name ADEN ADSC ADATE ADIF ADIE ADPS2 ADPS1 ADPS0 43 | set to 1 0 1 0 0 0 1 1 44 | 45 | ADEN = 1 enable ADC 46 | ADSC = 0 don't start ADC yet 47 | ADATE = 1 enable ADC auto trigger (i.e. use free running mode) 48 | ADIF = 0 don't set ADC interrupt flag 49 | ADIE = 0 don't set ADC interrupt enable 50 | 51 | ADPS2 = 0 52 | ADPS1 = 1 1 MHz clock / 8 = 125 kHz ADC clock 53 | ADPS0 = 1 54 | */ 55 | ADCSRA = 0b10100011; 56 | 57 | /* 58 | ADCSRB - ADC Control and Status Register B 59 | 60 | bit 7 6 5 4 3 2 1 0 61 | name - ACME - - - ADTS2 ADTS1 ADTS0 62 | set to 0 0 0 0 0 0 0 0 63 | 64 | bit 7 = 0 65 | ACME = 0 don't enable analog comparator multiplexer 66 | bit 5 = 0 67 | bit 4 = 0 68 | bit 3 = 0 69 | ADTS2 = 0 70 | ADTS1 = 0 free running mode 71 | ADTS0 = 0 72 | */ 73 | ADCSRB = 0b00000000; 74 | 75 | ADCSRA |= (1 << ADSC); // start ADC 76 | 77 | while (1) { // begin infinite loop 78 | PORTD = ADCH; // assign contents of ADC high register to Port D pins 79 | } 80 | return(0); // should never get here, this is to prevent a compiler warning 81 | } 82 | 83 | 84 | 85 | -------------------------------------------------------------------------------- /ADC_WithInterruptFreeRunning.c: -------------------------------------------------------------------------------- 1 | // ADC_WithInterruptFreeRunning.c 2 | 3 | // 10k ohm pot on PC5/ADC5 (pin 28) 4 | // 8 LEDs on Port D pins 5 | 6 | #ifndef F_CPU // if F_CPU was not defined in Project -> Properties 7 | #define F_CPU 1000000UL // define it now as 1 GHz unsigned long 8 | #endif 9 | 10 | #include // this is always included in AVR programs 11 | #include 12 | 13 | /////////////////////////////////////////////////////////////////////////////////////////////////// 14 | int main(void) { 15 | 16 | DDRD = 0xFF; // set Port D pins for output 17 | 18 | /* 19 | ADMUX - ADC Multiplexer Selection Register 20 | 21 | bit 7 6 5 4 3 2 1 0 22 | name REFS1 REFS0 ADLAR - MUX3 MUX2 MUX1 MUX0 23 | set to 0 1 1 0 0 1 0 1 24 | 25 | REFS1 = 0 use AVCC for reference voltage 26 | REFS0 = 1 27 | 28 | ADLAR = 1 left justify ADC result in ADCH/ADCL 29 | 30 | bit 4 = 0 31 | 32 | MUX3 = 0 use PC5/ADC5 (pin 28) for input 33 | MUX2 = 1 34 | MUX1 = 0 35 | MUX0 = 1 36 | */ 37 | ADMUX = 0b01100101; 38 | 39 | /* 40 | ADCSRA - ADC Control and Status Register A 41 | 42 | bit 7 6 5 4 3 2 1 0 43 | name ADEN ADSC ADATE ADIF ADIE ADPS2 ADPS1 ADPS0 44 | set to 1 0 1 0 1 0 1 1 45 | 46 | ADEN = 1 enable ADC 47 | ADSC = 0 don't start ADC yet 48 | ADATE = 1 enable ADC auto trigger (i.e. use free running mode) 49 | ADIF = 0 don't set ADC interrupt flag 50 | ADIE = 1 enable ADC interrupt 51 | 52 | ADPS2 = 0 53 | ADPS1 = 1 1 MHz clock / 8 = 125 kHz ADC clock 54 | ADPS0 = 1 55 | */ 56 | ADCSRA = 0b10101011; 57 | 58 | /* 59 | ADCSRB - ADC Control and Status Register B 60 | 61 | bit 7 6 5 4 3 2 1 0 62 | name - ACME - - - ADTS2 ADTS1 ADTS0 63 | set to 0 0 0 0 0 0 0 0 64 | 65 | bit 7 = 0 66 | ACME = 0 don't enable analog comparator multiplexer 67 | bit 5 = 0 68 | bit 4 = 0 69 | bit 3 = 0 70 | ADTS2 = 0 71 | ADTS1 = 0 free running mode 72 | ADTS0 = 0 73 | */ 74 | ADCSRB = 0b00000000; 75 | 76 | sei(); // enable interrupts 77 | 78 | ADCSRA |= (1 << ADSC); // start ADC 79 | 80 | while (1) { } // infinite loop 81 | 82 | return(0); // should never get here, this is to prevent a compiler warning 83 | } 84 | 85 | /////////////////////////////////////////////////////////////////////////////////////////////////// 86 | ISR(ADC_vect) { 87 | PORTD = ADCH; // assign contents of ADC high register to Port D pins 88 | } 89 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /ADC_SingleConversion.c: -------------------------------------------------------------------------------- 1 | // ADC_SingleConversion.c 2 | 3 | // 10k ohm pot on PC5/ADC5 (pin 28) 4 | // 8 LEDs on Port D pins 5 | 6 | #ifndef F_CPU // if F_CPU was not defined in Project -> Properties 7 | #define F_CPU 1000000UL // define it now as 1 GHz unsigned long 8 | #endif 9 | 10 | #include // this is always included in AVR programs 11 | 12 | #define BIT_IS_SET(byte, bit) (byte & (1 << bit)) 13 | #define BIT_IS_CLEAR(byte, bit) (!(byte & (1 << bit))) 14 | 15 | /////////////////////////////////////////////////////////////////////////////////////////////////// 16 | int main(void) { 17 | 18 | DDRD = 0xFF; // set Port D pins for output 19 | 20 | /* 21 | ADMUX - ADC Multiplexer Selection Register 22 | 23 | bit 7 6 5 4 3 2 1 0 24 | name REFS1 REFS0 ADLAR - MUX3 MUX2 MUX1 MUX0 25 | set to 0 1 1 0 0 1 0 1 26 | 27 | REFS1 = 0 use AVCC for reference voltage 28 | REFS0 = 1 29 | 30 | ADLAR = 1 left justify ADC result in ADCH/ADCL 31 | 32 | bit 4 = 0 33 | 34 | MUX3 = 0 use PC5/ADC5 (pin 28) for input 35 | MUX2 = 1 36 | MUX1 = 0 37 | MUX0 = 1 38 | */ 39 | ADMUX = 0b01100101; 40 | 41 | /* 42 | ADCSRA - ADC Control and Status Register A 43 | 44 | bit 7 6 5 4 3 2 1 0 45 | name ADEN ADSC ADATE ADIF ADIE ADPS2 ADPS1 ADPS0 46 | set to 1 0 0 0 0 0 1 1 47 | 48 | ADEN = 1 enable ADC 49 | ADSC = 0 don't start ADC yet 50 | ADATE = 0 don't enable ADC auto trigger (i.e. use single conversion mode) 51 | ADIF = 0 don't set ADC interrupt flag 52 | ADIE = 0 don't set ADC interrupt enable 53 | 54 | ADPS2 = 0 55 | ADPS1 = 1 1 MHz clock / 8 = 125 kHz ADC clock 56 | ADPS0 = 1 57 | */ 58 | ADCSRA = 0b10000011; 59 | 60 | /* 61 | ADCSRB - ADC Control and Status Register B 62 | 63 | bit 7 6 5 4 3 2 1 0 64 | name - ACME - - - ADTS2 ADTS1 ADTS0 65 | set to 0 0 0 0 0 0 0 0 66 | 67 | bit 7 = 0 68 | ACME = 0 don't enable analog comparator multiplexer 69 | bit 5 = 0 70 | bit 4 = 0 71 | bit 3 = 0 72 | ADTS2 = 0 73 | ADTS1 = 0 register ADCSRA bit ADATE set to 0 so these bits have no effect 74 | ADTS0 = 0 75 | */ 76 | ADCSRB = 0b00000000; 77 | 78 | while (1) { // begin infinite loop 79 | ADCSRA |= (1 << ADSC); // start ADC conversion 80 | while(BIT_IS_SET(ADCSRA, ADSC)) {} // wait here until the chip clears the ADSC bit for us, which means the ADC is complete 81 | PORTD = ADCH; // assign contents of ADC high register to Port D pins 82 | } 83 | return(0); // should never get here, this is to prevent a compiler warning 84 | } 85 | 86 | 87 | -------------------------------------------------------------------------------- /ADC_WithInterruptSingleConversion.c: -------------------------------------------------------------------------------- 1 | // ADC_WithInterruptSingleConversion.c 2 | 3 | // 10k ohm pot on PC5/ADC5 (pin 28) 4 | // 8 LEDs on Port D pins 5 | 6 | #ifndef F_CPU // if F_CPU was not defined in Project -> Properties 7 | #define F_CPU 1000000UL // define it now as 1 GHz unsigned long 8 | #endif 9 | 10 | #include // this is always included in AVR programs 11 | #include 12 | 13 | /////////////////////////////////////////////////////////////////////////////////////////////////// 14 | int main(void) { 15 | 16 | DDRD = 0xFF; // set Port D pins for output 17 | 18 | /* 19 | ADMUX - ADC Multiplexer Selection Register 20 | 21 | bit 7 6 5 4 3 2 1 0 22 | name REFS1 REFS0 ADLAR - MUX3 MUX2 MUX1 MUX0 23 | set to 0 1 1 0 0 1 0 1 24 | 25 | REFS1 = 0 use AVCC for reference voltage 26 | REFS0 = 1 27 | 28 | ADLAR = 1 left justify ADC result in ADCH/ADCL 29 | 30 | bit 4 = 0 31 | 32 | MUX3 = 0 use PC5/ADC5 (pin 28) for input 33 | MUX2 = 1 34 | MUX1 = 0 35 | MUX0 = 1 36 | */ 37 | ADMUX = 0b01100101; 38 | 39 | /* 40 | ADCSRA - ADC Control and Status Register A 41 | 42 | bit 7 6 5 4 3 2 1 0 43 | name ADEN ADSC ADATE ADIF ADIE ADPS2 ADPS1 ADPS0 44 | set to 1 0 0 0 1 0 1 1 45 | 46 | ADEN = 1 enable ADC 47 | ADSC = 0 don't start ADC yet 48 | ADATE = 0 don't enable ADC auto trigger (i.e. use single conversion mode) 49 | ADIF = 0 don't set ADC interrupt flag 50 | ADIE = 1 enable ADC interrupt 51 | 52 | ADPS2 = 0 53 | ADPS1 = 1 1 MHz clock / 8 = 125 kHz ADC clock 54 | ADPS0 = 1 55 | */ 56 | ADCSRA = 0b10001011; 57 | 58 | /* 59 | ADCSRB - ADC Control and Status Register B 60 | 61 | bit 7 6 5 4 3 2 1 0 62 | name - ACME - - - ADTS2 ADTS1 ADTS0 63 | set to 0 0 0 0 0 0 0 0 64 | 65 | bit 7 = 0 66 | ACME = 0 don't enable analog comparator multiplexer 67 | bit 5 = 0 68 | bit 4 = 0 69 | bit 3 = 0 70 | ADTS2 = 0 71 | ADTS1 = 0 register ADCSRA bit ADATE set to 0 so these bits have no effect 72 | ADTS0 = 0 73 | */ 74 | ADCSRB = 0b00000000; 75 | 76 | sei(); // enable interrupts 77 | 78 | ADCSRA |= (1 << ADSC); // start ADC 79 | 80 | while (1) { } // infinite loop 81 | 82 | return(0); // should never get here, this is to prevent a compiler warning 83 | } 84 | 85 | /////////////////////////////////////////////////////////////////////////////////////////////////// 86 | ISR(ADC_vect) { 87 | PORTD = ADCH; // assign contents of ADC high register to Port D pins 88 | ADCSRA |= (1 << ADSC); // start next ADC 89 | } 90 | 91 | 92 | 93 | --------------------------------------------------------------------------------