1

我正在尝试从 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;
}
}
4

1 回答 1

0

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

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

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

但是为什么要使用自由运行模式呢?你想要一个中断。因此您可以选择源和触发测量并等待中断。然后手动开始下一次测量。

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

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

于 2014-09-22T13:34:24.573 回答