57 lines
1.1 KiB
C
57 lines
1.1 KiB
C
#include "adc.h"
|
|
|
|
void adc_init(uint8_t vsel)
|
|
{
|
|
PRR &= ~_BV(PRADC);
|
|
ADMUX = (ADMUX & ~(_BV(REFS1) | _BV(REFS0))) | vsel;
|
|
ADCSRA = _BV(ADEN);
|
|
|
|
#if F_CPU >= (ADC_MAX_FREQ * 128)
|
|
#error F_CPU is too high for ADC prescaler!
|
|
#elif F_CPU >= (ADC_MAX_FREQ * 64)
|
|
ADCSRA |= _BV(ADPS2) | _BV(ADPS1) | _BV(ADPS0);
|
|
#elif F_CPU >= (ADC_MAX_FREQ * 32)
|
|
ADCSRA |= _BV(ADPS2) | _BV(ADPS1);
|
|
#elif F_CPU >= (ADC_MAX_FREQ * 16)
|
|
ADCSRA |= _BV(ADPS2) | _BV(ADPS0);
|
|
#elif F_CPU >= (ADC_MAX_FREQ * 8)
|
|
ADCSRA |= _BV(ADPS2);
|
|
#elif F_CPU >= (ADC_MAX_FREQ * 4)
|
|
ADCSRA |= _BV(ADPS1) | _BV(ADPS0);
|
|
#elif F_CPU >= (ADC_MAX_FREQ * 2)
|
|
ADCSRA |= _BV(ADPS1);
|
|
#elif F_CPU >= (ADC_MAX_FREQ >> 1)
|
|
ADSRA |= _BV(ADPS0);
|
|
#else
|
|
#error F_CPU is too slow for ADC to run well!
|
|
#endif
|
|
}
|
|
|
|
uint16_t adc_read(uint8_t pin)
|
|
{
|
|
adc_start(pin);
|
|
adc_wait();
|
|
return adc_result();
|
|
}
|
|
|
|
void adc_start(uint8_t pin)
|
|
{
|
|
ADMUX = (ADMUX & 0xF0) | pin;
|
|
ADCSRA |= _BV(ADSC);
|
|
}
|
|
|
|
uint16_t adc_result()
|
|
{
|
|
return ADC;
|
|
}
|
|
|
|
uint8_t adc_finished()
|
|
{
|
|
return (ADCSRA & _BV(ADSC))?0xFF:0;
|
|
}
|
|
|
|
void adc_wait()
|
|
{
|
|
for (;adc_finished() == 0;);
|
|
}
|