Greetings
I'm setting up the ADC of the atmel 326 in autotrigger mode, triggered by timer 0. I'm toggling pin6 when the T0 interrupts, and pin2 when the ADC interrupts (so when it's done converting).
#include <Arduino.h>
#define WINDOW_LENGTH 5000
uint16_t index;
uint16_t table[WINDOW_LENGTH];
uint16_t analog_value;
void set_ADC_channel(uint8_t channel) {
ADMUX = (ADMUX & 0xF0)| //safety mask
(channel & 0x0F); //set ADC channel
}
void init_ADC(void) {
ADMUX = 0;
ADMUX |= (1 << REFS0); //AVcc voltage reference
set_ADC_channel(0);
ADCSRA = 0;
ADCSRA |= (1 << ADATE)| //auto trigger enable
(1 << ADIE)| //ADC interrupt enable
(1 << ADPS2)| //ADC prescaler = 128 -> 125kHz
(1 << ADPS1)|
(1 << ADPS0);
ADCSRB = 0;
ADCSRB |= (1 << ADTS1)| //set ADC trigger source to T0 compare match
(1 << ADTS0);
}
void enable_ADC(void) {
ADCSRA |= 1 << ADEN; //enable ADC
}
void init_T0(void) {
//set timer0 interrupt at 2kHz
TCCR0A = 0; //T0 control register
TCCR0B = 0;
TCNT0 = 0; //init counter value to 0
TCCR0B |= (1 << CS01)| //set 64 prescaler
(1 << CS00);
OCR0A = 124; //set compare match register = 16e6 / (2e3*64) - 1
TCCR0A |= (1 << COM0A0)| //toggle PD6/OC0A pin on compare match
(1 << WGM01); //turn on CTC mode
}
void enable_T0(void) {
TIMSK0 |= (1 << OCIE0A); //enable T0 interrupt
}
void setup() {
DDRD |= (1 << PD2)|(1 << PD6); //set PD2 and PD6 as output
Serial.begin(9600);
index = 0;
cli(); //stop interrupts
init_ADC();
enable_ADC();
init_T0();
enable_T0();
sei(); //enable interrupts
}
void loop() {
}
ISR(TIMER0_COMPA_vect){
}
ISR(ADC_vect) {
if (index < WINDOW_LENGTH) {
TIFR0 |= (1 << OCF0A); //clear timer compare match flag
PIND = (1 << PD2); //toggle pin PD2
uint8_t val_8bit = ADCL;
analog_value = val_8bit | (ADCH << 8); //read analog value
//table[index] = analog_value;
++index;
}
}
The code above works, I see the led6 always burning, and led2 for a couple of seconds. But when I add "table[index] = analog_value;" in the ADC interrupt handler to store the value in the memory for later processing, led6 and led2 doesn't burn, not at all.
How is that? It's wierd that adding that line, not only the ADC interrupt gets broken but also the T0 interrupt.
Also, I found that I needed to include the empty T0 interrupt in my code for the ADC to work. I find this strange as I thought that the ADC gets triggered by the rising/falling edge of the T0 interrupt signal and that that happened by HW by default whether I included it in SW or not.
Thanks