从ATMEGA128上的多个ADC通道读取数据

时间:2014-09-22 08:22:28

标签: avr adc

我试图从ATMega128开发板上的两个模拟红外传感器读取值,然后通过PWM输出缩放表示。当我将两个PWM波连接到示波器时,它们保持相同,但情况并非如此。我的PWM代码很好,所以我认为问题出在我的代码中,用于读取ADC的通道0和1。

int sens1,sens2,sens3;
volatile const uint8_t adc1 = (1<<ADLAR) | (0<<MUX0)|(0<<MUX1);
volatile const uint8_t adc2 = (1<<ADLAR) | (1<<MUX0)|(0<<MUX1);

void main(void)
{


ADCSRA |= (1 << ADPS2) | (1 << ADPS1) | (1 << ADPS0); 
ADMUX |= (1 << REFS0); // Set ADC reference to AVCC
ADMUX |= (1 << ADLAR); // Left adjust ADC result to allow easy 8 bit reading
ADCSRA |= (1 << ADFR);  // Set ADC to Free-Running Mode
ADCSRA |= (1 << ADEN);  // Enable ADC
ADCSRA |= (1 << ADIE);  // Enable ADC Interrupt
sei();  // Enable Global Interrupts
ADCSRA |= (1 << ADSC);  // Start A2D Conversions

while (1)
{
}
}

ISR(ADC_vect)
{

static uint8_t firstTime = 1;
static uint8_t val;

val = ADCH*100;

if (firstTime == 1){
firstTime = 0;
}
else if (ADMUX == adc1)
{
    ADMUX = adc2;
    OCR3A = val;
}

else if (ADMUX == adc2)
{
    ADMUX = adc1;
    OCR1C = val;
}
}

1 个答案:

答案 0 :(得分:0)

我认为您应该在输入频道更改后将firstTime设置为1。 请参考数据表:

  

更改频道选择时,用户应观察   遵循以下准则以确保选择正确的频道:

     

[...]   在自由运行模式下,始终选择之前的频道   开始第一次转换。可以改变频道选择   将一个写入ADSC后的一个ADC时钟周期。但是,最简单的   方法是等待第一次转换完成,然后   更改频道选择。由于下一次转换已经存在   自动启动,下一个结果将反映前一个   频道选择。后续转换将反映新频道   选择。

但为什么要使用Free Run Mode?你想要一个中断。因此,您可以选择源和触发测量并等待中断。然后手动开始下一次测量。

提醒我的另一件事是uint8_t结果乘以100。 你确定这不会溢出吗? ADC通道的输入电压范围是多少?

另一个原因可能是采样频率。你选择了一个非常高的预分频器。 ADC需要至少50kHz的时钟。所以你的AVR应该在&gt;运行为6MHz。检查您的保险丝设置是否设置为使用外部时钟源。还有一件事。 Fuse Bits的文档说默认情况下AtMega103兼容模式似乎是活动的。您可以参考日期表,这可能也会影响您的问题。