paperbag085
paperbag085

Reputation: 21

Unable to trigger ADC interrupt

I'm trying to simply get an analog reading from A0 on my arduino Pro mini, but I cannot get the values stored in the adc register. What is supposed to happen is the analog signal will be put in registers ADCL & ADCH and then the ADC interrupt will trigger. I have a voltage divider set up on A0 that should just read 2.5V but my interrupt is not triggering and i cannot get values from ADCH or ADCL. I could get a reading in arduino so I know the hardware works. when i run this program i get a continuous print of 0 to my terminal which tells me the values of low and high never change as they should in the interrupt.

Here is my code:

# define F_CPU 16000000L
#include "time.h"
#include <avr/io.h>
#include <math.h>
#include <util/delay.h>    // including the avr delay lib
#include <util/delay.h>     // Including the avr delay lib
#include "usart.h"
#include "usart.cpp"
#include <stdio.h>
#include <avr/interrupt.h>

uint8_t low,high;

int main(void)
{

TCCR0B = (1<<CS02) | (1<<CS00);
USART_Init(MYUBRR);

DDRC = 0x0 ;
ADCSRA = (1<<ADEN) | (0<<ADIF); //activate adc & clear ADIF
ADMUX = (0<<ADLAR); //keep right adjusted
ADMUX = (1<<REFS0) | (0<<MUX2) | (0<<MUX1) | (0<<MUX0);//set ref as vcc, input as 0
ADCSRA = (1<<ADIE)  | (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0);//enable adc interrupt & divide clock by 124
DIDR0 = (0<<ADC0D); 

sei();

ADCSRA = (1<<ADSC);//begin conversion



while (1) 
{
        while(ADSC==1)//wait for conversion to complete
        {
            sei();
        }

    USART_Send_int(low);
    USART_Send_int(high);
    _delay_ms(100);

    ADCSRA = (1<<ADSC);

}
}

ISR(ADC_vect) //interrupt to trigger when conversion is complete
{
low = ADCL;
high = ADCH;
//ADCSRA = (1<<ADSC);
}

Upvotes: 0

Views: 1183

Answers (1)

David Grayson
David Grayson

Reputation: 87486

You should declare low and high as volatile since you are accessing them from an interrupt and the main loop:

volatile uint8_t low;
volatile uint8_t high;

Otherwise, the compiler is free to optimize your loop by moving the readings of those variables to be before the loop.

Alternatively, you could try putting a memory barrier in your loop, but that is the less-traveled road: most embedded developers tend to just use volatile.

I didn't test your code so there might still be other errors.

To debug this further, you should try putting low = 44; and high += 1; in your interrupt just to make sure the interrupt is running.

Upvotes: 1

Related Questions