/* Test des Free run mode im ADC ATmega328P, aka Arduino Uno/Micro/Nano */ #define F_CPU 16000000UL #include #include #include #include #include #define ADC_CHANNELS 3 #define ADC_AVERAGE_CNT 4 #define ADC_PRESCALER 16 volatile uint16_t adc_avg[ADC_CHANNELS]; volatile bool adc_run; // ADC initialisieren void adc_init(void) { uint8_t tmp; ADMUX = (1 << REFS0); // AVcc als Referenz, ADC0 als Eingang switch(ADC_PRESCALER) { case 4: tmp = 2; break; case 8: tmp = 3; break; case 16: tmp = 4; break; case 32: tmp = 5; break; case 64: tmp = 6; break; case 128: tmp = 7; break; default : tmp = 1; break; // Prescaler 2 und alles andere } ADCSRA = (1 << ADEN) | // ADC einschalten (1 << ADIE) | // Interrupt einschalten tmp; // Prescaler sei(); // globale Interrupts aktivieren } // ISR für den ADC-Interrupt ISR(ADC_vect) { static uint8_t channel; static uint16_t adc_accu[ADC_CHANNELS]; static uint8_t avg_cnt; uint8_t i, next; PINB = (1<= ADC_CHANNELS) { channel = 0; avg_cnt++; if (avg_cnt == ADC_AVERAGE_CNT) { avg_cnt = 0; for (i=0; i= ADC_CHANNELS) next = 0; ADMUX = (next & 0x0F) | (ADMUX & ~0xF); } void start_adc_avg(void) { ADCSRA |= (1<