You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
atmega-geiger/lib/porklib/adc.c

68 lines
1.5 KiB

2 years ago
#include <avr/io.h>
#include <stdbool.h>
#include <stdint.h>
#include "calc.h"
#include "adc.h"
/** Initialize the ADC */
void adc_init()
{
ADCSRA |= _BV(ADPS2) | _BV(ADPS1) | _BV(ADPS0); // 128 prescaler -> 125 kHz
// ADCSRA |= _BV(ADPS2) | _BV(ADPS0); // 32 prescaler -> 500 kHz, good for 8-bit measurement
ADMUX |= _BV(REFS0) | _BV(REFS1); // Voltage reference = internal 1.1V
sbi(ADCSRA, ADEN); // Enable ADC
}
/** Disable AD */
void adc_disable()
{
cbi(ADCSRA, ADEN);
}
/** Sample analog pin with 8-bit precision */
uint8_t adc_read_byte(uint8_t channel)
{
set_low_nibble(ADMUX, channel); // Select channel to sample
sbi(ADMUX, ADLAR); // Align result to left
sbi(ADCSRA, ADSC); // Start conversion
while (bit_is_high(ADCSRA, ADSC)); // Wait for it...
return ADCH; // The upper 8 bits of ADC result
}
/** Sample analog pin with 10-bit precision */
uint16_t adc_read_word(uint8_t channel)
{
set_low_nibble(ADMUX, channel); // Select channel to sample
cbi(ADMUX, ADLAR); // Align result to right
sbi(ADCSRA, ADSC); // Start conversion
while (get_bit(ADCSRA, ADSC)); // Wait for it...
return ADCW; // The whole ADC word (10 bits)
}
/** Sample analog pin with 10-bit precision */
void adc_async_start_measure_word(uint8_t channel)
{
set_low_nibble(ADMUX, channel); // Select channel to sample
cbi(ADMUX, ADLAR); // Align result to right
sbi(ADCSRA, ADSC); // Start conversion
}
bool adc_async_ready()
{
return 0 == get_bit(ADCSRA, ADSC);
}
uint16_t adc_async_get_result_word() {
return ADCW; // The whole ADC word (10 bits)
}