无法触发ADC中断

时间:2017-09-28 22:43:59

标签: atmega adc atmelstudio

我试图在我的arduino Pro mini上简单地从A0获取模拟读数,但我无法获得存储在adc寄存器中的值。 应该发生的是模拟信号将被放入寄存器ADCL& ADCH然后ADC中断将触发。 我在A0上设置了一个分压器,它应该读取2.5V,但我的中断没有触发,我无法从ADCH或ADCL获取值。我可以用arduino阅读,所以我知道硬件有效。当我运行这个程序时,我得到一个连续打印0到我的终端,告诉我低和高的值永远不会改变,因为他们应该在中断。

这是我的代码:

# 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);
}

1 个答案:

答案 0 :(得分:1)

您应该将lowhigh声明为volatile,因为您正在从中断和主循环访问它们:

volatile uint8_t low;
volatile uint8_t high;

否则,编译器可以通过将这些变量的读数移动到循环之前来自由优化循环。

或者,您可以尝试在循环中设置一个内存屏障,但这是一条不太常见的道路:大多数嵌入式开发人员倾向于使用volatile

我没有测试您的代码,因此可能还有其他错误。

为了进一步调试,您应该尝试将low = 44;high += 1;放在中断中,以确保中断正在运行。