/*
* Lab5_Task2_ADC_Potentiometer.c
*
* Created: 2024-04-26 19:41:50
* Author : Erik Karlsson
*/
#include <avr/io.h>
#include <avr/interrupt.h>
#define F_CPU 16000000UL
// I/O SETTINGS
#define D6_LED PD6
#define D6_TO_OUTPUT (1 << D6_LED)
// TIMER0 SETTINGS
#define FASTPWM (1 << WGM01) | (1 << WGM00)
#define CLEAR_ON_MATCH_NON_INVERTED (1 << COM0A1) | (0 << COM0A0)
#define PRESCALER_NONE (0 << CS02) | (0 << CS01) | (1 << CS00)
// ADC SETTINGS
#define ENABLE_ADC (1 << ADEN)
#define AUTO_CONVERSION (1 << ADATE)
#define INTERNAL_VOLTAGE_REF (0 << REFS1) | (0 << REFS0)
#define ADC2_SELECTED (0 << MUX3) | (0 << MUX2) | (1 << MUX1) | (0 << MUX0)
#define ENABLE_ADC_INTERRUPT (1 << ADIE)
#define PRESCALER_2 (0 << ADPS2) | (0 << ADPS1) | (0 << ADPS0)
#define PRESCALER_4 (0 << ADPS2) | (1 << ADPS1) | (0 << ADPS0)
#define PRESCALER_8 (0 << ADPS2) | (1 << ADPS1) | (1 << ADPS0)
#define PRESCALER_16 (1 << ADPS2) | (0 << ADPS1) | (0 << ADPS0)
#define PRESCALER_32 (1 << ADPS2) | (0 << ADPS1) | (1 << ADPS0)
#define PRESCALER_64 (1 << ADPS2) | (1 << ADPS1) | (0 << ADPS0)
#define PRESCALER_128 (1 << ADPS2) | (1 << ADPS1) | (1 << ADPS0)
#define ADC_LEFT_ADJUST (0 << ADLAR)
#define FREE_RUNNING (0 << ADTS2) | (0 << ADTS2) | (0 << ADTS2)
#define START_CONVERSION (1 << ADSC)
#define CONVERSION_IN_PROGRESS (ADCSRA & (1 << ADSC))
int main(void)
{
Serial.begin(9600);
INIT_TIMER0();
LED_INIT();
ADC_INIT();
//sei();
while (1)
{
// POLLING
// Remain here until conversion is complete
while (CONVERSION_IN_PROGRESS);
// Make sure our datatype is large enough
uint16_t adc_value = ADC;
// Remap 0-1024 to 0-255
unsigned int converted_value = ((uint32_t)adc_value * 255) / 1024;
// Store value in Compare A register
OCR0A = converted_value;
Serial.println(adc_value);
// Start next conversion
ADCSRA |= START_CONVERSION;
}
}
void ADC_INIT(){
ADCSRA = ENABLE_ADC | ENABLE_ADC_INTERRUPT | PRESCALER_2 | START_CONVERSION;
ADCSRB = FREE_RUNNING;
ADMUX = INTERNAL_VOLTAGE_REF | ADC2_SELECTED;
}
void INIT_TIMER0(){
TCCR0A = FASTPWM | CLEAR_ON_MATCH_NON_INVERTED;
TCCR0B = PRESCALER_NONE;
}
void LED_INIT(void){
DDRD = D6_TO_OUTPUT;
}
ISR(ADC_vect){
// ADC is 10-bit. Max 1024
uint16_t adc_value = ADC;
unsigned int converted_value = ((uint32_t)adc_value * 255) / 1024;
OCR0A = converted_value;
//Serial.println(ADC);
Serial.println(converted_value);
ADCSRA |= START_CONVERSION;
}