АЦП, прерывания, несколько каналов

Тема в разделе "Микроконтроллеры AVR", создана пользователем Мерзкий Гуру, 29 дек 2016.

  1. Всем здравствуйте.

    Хочу поиграться с прерываниями по завершению преобразования АЦП.
    В примерах вроде всё понятно - задал номер канала, разрешил прерывания, в обработчике прерывания прочитал значения.

    А как сделать аналогичное считывание с нескольких каналов?
    В обработчике прерывания можно менять канал?
    А прочитать в обработчике текущее значение ADMUX можно, с какого канала данные?
     
  2. rkit

    rkit Гуру

    Храните в переменной текущий канал, в обработчике меняете канал и переменную.
     
  3. rkit

    rkit Гуру

    Вот такой кусок кода всегда использую. Тут кроме этого сделан двойной опрос АЦП по каждому каналу, первый результат игноруется. Не знаю, насколько это нужно. Можете выкинуть всё связанное с ADC_update .
    Код (C++):
    ISR(ADC_vect)
    {
      if (ADC_update){
        AnalogValues[cur_pin] = ADCL|(ADCH << 8);
        cur_pin++;
        if (cur_pin >= ANALOG_COUNT) cur_pin = 0;

        ADMUX = (analog_reference << 6) | (AnalogPins[cur_pin] & 0x07);
        ADC_update = false;
      }
      else
        ADC_update    = true;  
    }
     
     
  4. Спасибо.

    А вот это я считаю потенциально некорректным:
    AnalogValues[cur_pin] = ADCL|(ADCH << 8);

    Теоретически, важен порядок считывания, а как это выражение оптимизирует компилятор, в каком порядке вычисления, есть на это стандарты?
    Я бы перестраховался, написал в бы
    AnalogValues[cur_pin] = ADCL; AnalogValues[cur_pin]|=ADCH << 8;
     
  5. Впрочем, для вытаскивания результатов преобразования есть ADC.
    Можно писать просто
    AnalogValues[cur_pin] = ADC;
    Правда, не знаю, как это будет работать при смене порядка байт.

    А ваша ADC_update - нужна, первое выданное значение после смены канала - это значение канала до смны, и его нужно игнорировать.
    Подозреваю, что есть другой, более красивый, способсбросить уже начавшееся преобразование по старому каналу, но пока не нашел.
     
  6. Продолжу тему. Теперь про free running mode.
    Я, для основы, брал вот этот код: http://robotosha.ru/arduino/analog-measurements-arduino.html

    Кто-нибудь, кроме меня, видит, что афтар ставит преобразования по таймеру вместо free running mode? Там так написано
    ADCSRB=0x40;// включаем АЦ коналы MUX, режим скользящей выборки

    Но в даташите написано, что free running mode - это когда все биты ATDS* нули, а 0x40 это не нули, это ATDS2=1.

    Даташит: http://www.atmel.com/images/Atmel-8...PA-168A-168PA-328-328P_datasheet_Complete.pdf

    А теперь собственно, вопрос: почему при смене метода считывания с "по таймеру" на "free run", меняются считываемые показания?

    Код выложить?