Чтение с нескольких каналов АЦП на ATMEGA128

Я пытаюсь считать значение с двух аналоговых инфракрасных датчиков на плате разработчика ATMega128, а затем вывести масштабированное представление через ШИМ. Когда я подключаю две волны ШИМ к осциллографу, они остаются идентичными, чего не должно быть. Мой код PWM в порядке, поэтому я думаю, что проблема в моем коде для чтения с каналов 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;
}
}

person user27365    schedule 22.09.2014    source источник
comment
Код выглядит хорошо с первого взгляда. Я бы проверил, что каждый канал АЦП дает ожидаемые результаты без переключения между каналами, чтобы сузить его.   -  person Rev    schedule 22.09.2014
comment
Каждый канал дает ожидаемые результаты   -  person user27365    schedule 22.09.2014


Ответы (1)


Я думаю, вы должны установить firstTime в 1 после изменения входного канала. пожалуйста, обратитесь к паспорту для этого:

При изменении выбора каналов пользователь должен соблюдать следующие рекомендации, чтобы убедиться, что выбран правильный канал:

[...] В режиме автономной работы всегда выбирайте канал перед началом первого преобразования. Выбор канала может быть изменен через один такт АЦП после записи одного такта в ADSC. Однако самый простой способ - дождаться завершения первого преобразования и затем изменить выбор канала. Поскольку следующее преобразование уже началось автоматически, следующий результат будет отражать предыдущий выбор канала. Последующие преобразования будут отражать выбор нового канала.

Но зачем вообще использовать режим Free Running? Вы хотите, чтобы вас прервали. Таким образом, вы можете выбрать источник и запустить измерение и дождаться прерывания. Затем вручную запустите следующее измерение.

Еще одна вещь, которая меня настораживает, - это умножение результата uint8_t на 100. Вы уверены, что это не приведет к переполнению? Каков диапазон входных напряжений наших каналов АЦП?

Другой причиной может быть частота дискретизации. Вы выбрали очень высокий предделитель. Для АЦП требуется частота не менее 50 кГц. Так что ваш AVR должен работать на частоте> 6 МГц. Убедитесь, что настройки предохранителя настроены на использование внешнего источника синхронизации. И вот еще. В документации Fuse Bits указано, что режим совместимости с AtMega103 активен по умолчанию. Вы можете сослаться на таблицу с датами, возможно, это также повлияет на вашу проблему.

person vlad_tepesch    schedule 22.09.2014