/* * ADC.c * * Program zapala diody w miarę, jak napięcie na ADC rośnie. * Możliwa modyfikacja/zadanie: diody zapalają się w różnej kolejności lub * jak napięcie na ADC maleje. * */ #include #include uint16_t adc_result; // deklaracja zmiennej, do której zapisany // zostanie wynik konwersji przetwornika, int main(void) { /* * konfiguracja używanych portów */ PORTA.DIRCLR = PIN0_bm; // pin 0 portu A ustwiony jako wejście (tu // podłączony jest potencjometr), PORTB.DIRSET = PIN0_bm|PIN1_bm|PIN2_bm|PIN3_bm; // piny od 0 do 3 ustawione jako wyjścia, PORTB.OUTCLR = PIN0_bm|PIN1_bm|PIN2_bm|PIN3_bm; // wyłączenie diod, /* * konfiguracja ADC */ ADCA.PRESCALER = ADC_PRESCALER_DIV16_gc; // 2MHZ/16=125kHz ustalenie zegara dla ADC, ADCA.CH0.INTFLAGS = 0x01; // zerowanie flag przerwań, ADCA.INTFLAGS = ADC_CH0IF_bm; PMIC.CTRL = PMIC_HILVLEN_bm; // odblokowanie przerwań o wysokim // priorytecie (ADC ma wysoki priorytet), ADCA.CH0.INTCTRL = ADC_CH_INTLVL1_bm|ADC_CH_INTLVL0_bm; //włączenie przerwań ADC, domyślnie //zgłaszane po zakończeniu konwersji, ADCA.REFCTRL = ADC_REFSEL_INTVCC2_gc; // ustawienie napięcia odniesienia na Vcc/2, ADCA.CTRLB = ADC_CONMODE_bm|ADC_FREERUN_bm; // tryb signed (ze znakiem) (aby móc używać // gain'a), freerun - pomiary wykonują się // jeden por drugim, ADCA.CH0.CTRL = ADC_CH_GAIN_DIV2_gc | ADC_CH_INPUTMODE_DIFFWGAIN_gc; // ustawienie wzmocnienia kanału 0 na równe // 0.5 (aby dopasować napięcie 3.3 do // referencyjnego) oraz ustawienie pomiaru // różnicowego ze wzmocnieniem, ADCA.CH0.MUXCTRL = ADC_CH_MUXPOS_PIN0_gc | ADC_CH_MUXNEG_INTGND_MODE4_gc; // podłączenie wewnętrznej masy do // wejścia ujemnego ADC, ADCA.CTRLA = ADC_ENABLE_bm; // włączenie ADC, sei(); // odblokowanie przerwań, while(1) { cli(); //zablokowanie przerwań na czas //interpretowania wyniku, if (adc_result < 400 || adc_result > 2048) { PORTB.OUTCLR = PIN0_bm|PIN1_bm|PIN2_bm|PIN3_bm; } else if (adc_result > 400 && adc_result < 800) { PORTB.OUTSET = PIN0_bm; PORTB.OUTCLR = PIN1_bm|PIN2_bm|PIN3_bm; } else if (adc_result > 800 && adc_result < 1200) { PORTB.OUTSET = PIN0_bm|PIN1_bm; PORTB.OUTCLR = PIN2_bm|PIN3_bm; } else if (adc_result > 1200 && adc_result < 1600) { PORTB.OUTSET = PIN0_bm|PIN1_bm|PIN2_bm; PORTB.OUTCLR = PIN3_bm; } else if (adc_result > 1600) PORTB.OUTSET = PIN0_bm|PIN1_bm|PIN2_bm|PIN3_bm; sei(); //odblokowanie przerwań, } } /* * obsługa przerwania od ADC */ ISR(ADCA_CH0_vect) { adc_result = ADCA.CH0.RES & 0b0000111111111111; // odczytanie 12 bitowego wyniku, // maska użyta, gdyż wynik zapisany jest // w 16 bitowym rejestrze, // gdzie niekoniecznie są 0 na // ostatnich 4 bitach, }