simon says with pro mini, display, ws2812 and touch keys
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-simon/lib/adc.c

77 lines
1.5 KiB

#include <avr/io.h>
#include <stdint.h>
#include <stdbool.h>
#include "calc.h"
#include "adc.h"
/** Initialize the ADC */
void adc_init(enum ADC_Prescaller presc)
{
ADCSRA |= presc; // 128 prescaler -> 125 kHz
ADMUX |= _BV(REFS0); // Voltage reference
sbi(ADCSRA, ADEN); // Enable ADC
}
/** Disable ADC */
void adc_disable(void)
{
cbi(ADCSRA, ADEN);
}
/** Enable ADC */
void adc_enable(void)
{
sbi(ADCSRA, ADEN);
}
/** Start a new conversion */
void adc_start_conversion(uint8_t channel)
{
set_low_nibble(ADMUX, channel); // Select channel to sample
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;
}
/** 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_convert_8bit(uint8_t channel)
{
adc_convert(channel);
return adc_read_8bit();
}
/** Sample analog pin with 10-bit precision */
uint16_t adc_convert_10bit(uint8_t channel)
{
adc_convert(channel);
return adc_read_10bit();
}