ADC new APIs and bugfix for 10bit

master
Ondřej Hruška 7 years ago
parent eaf8623772
commit cfdc18d3c4
  1. 46
      lib/adc.c
  2. 20
      lib/adc.h

@ -1,5 +1,6 @@
#include <avr/io.h>
#include <stdint.h>
#include <stdbool.h>
#include "calc.h"
#include "adc.h"
@ -8,7 +9,7 @@
void adc_init(enum ADC_Prescaller presc)
{
ADCSRA |= presc; // 128 prescaler -> 125 kHz
ADMUX |= _BV(REFS0); // Voltage reference
ADMUX |= _BV(REFS0); // Voltage reference
sbi(ADCSRA, ADEN); // Enable ADC
}
@ -24,26 +25,53 @@ void adc_enable(void)
sbi(ADCSRA, ADEN);
}
static void adc_convert(uint8_t channel)
/** Start a new conversion */
void adc_start_conversion(uint8_t channel)
{
set_low_nibble(ADMUX, channel); // Select channel to sample
sbi(ADMUX, ADLAR); // Align result to left
cbi(ADMUX, ADLAR); // Align result to right
sbi(ADCSRA, ADSC); // Start conversion
}
/** Check if ADC is done converting */
bool adc_ready(void)
{
return bit_is_low(ADCSRA, ADSC);
}
/** Read the result of last conversion with 8bit precision */
uint8_t adc_read_8bit()
{
uint8_t low = ADCL;
uint8_t high = ADCH;
return low >> 2 | high << 6;
}
while (bit_is_high(ADCSRA, ADSC)); // Wait for it...
/** Read the result of last conversion with 10bit precision */
uint16_t adc_read_10bit()
{
uint8_t low = ADCL;
uint8_t high = ADCH;
return ((uint16_t) high << 8) | low;
}
/** Start ADC conversion and wait for the result */
static void adc_convert(uint8_t channel)
{
adc_start_conversion(channel);
while (!adc_ready()); // Wait for it...
}
/** Sample analog pin with 8-bit precision */
uint8_t adc_read_byte(uint8_t channel)
uint8_t adc_convert_8bit(uint8_t channel)
{
adc_convert(channel);
return ADCH; // The upper 8 bits of ADC result
return adc_read_8bit();
}
/** Sample analog pin with 10-bit precision */
uint16_t adc_read_word(uint8_t channel)
uint16_t adc_convert_10bit(uint8_t channel)
{
adc_convert(channel);
return ADCW; // The whole ADC word (10 bits)
return adc_read_10bit();
}

@ -25,8 +25,20 @@ void adc_disable(void);
/** Enable (already initialized) ADC */
void adc_enable(void);
/** Sample analog pin with 8-bit precision */
uint8_t adc_read_byte(uint8_t channel);
/** Start a new conversion */
void adc_start_conversion(uint8_t channel);
/** Sample analog pin with 10-bit precision */
uint16_t adc_read_word(uint8_t channel);
/** Check if ADC is done converting */
bool adc_ready(void);
/** Read the result of last conversion with 8bit precision */
uint8_t adc_read_8bit(void);
/** Read the result of last conversion with 10bit precision */
uint16_t adc_read_10bit(void);
/** Sample analog pin with 8-bit precision. Blocking! */
uint8_t adc_convert_8bit(uint8_t channel);
/** Sample analog pin with 10-bit precision. Blocking! */
uint16_t adc_convert_10bit(uint8_t channel);

Loading…
Cancel
Save