Когда АЦП снова начинает читать в режиме прерывания?

adc

Простой вопрос: я настроил АЦП на чтение в "непрерывном" режиме/режиме прерывания и считываю следующим образом:

ISR(ADC_vect) {
   int val = ADCL;
   val += ADCH << 8;
   ... // Код для чтения здесь.
   }

Мой вопрос: начинает ли ADC новое чтение, как только я прочитаю регистр ADCH, или он ждет завершения кода внутри прерывания? По сути, мне нужно знать, не снизит ли количество инструкций в прерывании мою скорость чтения.

У меня нет осциллографа или какого-либо другого способа достаточно точного измерения скорости чтения, чтобы понять, влияют ли на скорость несколько дополнительных строк кода или нет.

, 👍0


2 ответа


0

Хорошо, теперь я уверен, что знаю ответ на этот вопрос после еще нескольких тестов. Я поэкспериментировал с количеством инструкций, выполняемых внутри вызова прерывания АЦП, и просто замерил время с помощью micros(). Хотя это не дало мне сверхточной точности, было явное и быстрое падение частоты чтения, когда количество циклов ЦП, необходимых внутри вызова прерывания, превышало количество циклов ЦП, необходимых для АЦП, в то время как частота почти не влияла, когда циклы ЦП необходимых для инструкций, было меньше, чем тактов, необходимых для АЦП. Я могу понять это только в том случае, если АЦП продолжает работать независимо от кода внутри прерывания.

Если кто-то захочет меня поправить/добавить некоторые детали, я буду очень рад. Но для моих целей этого ответа достаточно :)

,

2

Ваш ответ правильный. АЦП действительно продолжает работать независимо от Что делает ISR. Есть, однако, момент, который я хотел бы сделать яснее. Вы спросили:

Мой вопрос: начинает ли ADC новое чтение, как только я прочитать регистр ADCH или он ждет код внутри прервать, чтобы закончить?

АЦП начинает новое считывание, как только оно завершено, принимая предыдущее значение. один, независимо от того, читаете ли вы ADCH или нет. Когда ваш ISR начинается, АЦП уже занят выполнением следующего преобразования. Этот гарантирует стабильную скорость преобразования, при одном аналого-цифровом преобразовании каждые ровно 13 тактов АЦП.

Кроме того, вы можете прочитать результат с помощью

int val = ADC;

Нет необходимости читать байты отдельно, если только вы не используете очень древний версия gcc, которая не умеет читать 16-битный регистр.

,

Спасибо за разъяснение :) Быстрый несвязанный вопрос (если вы не знаете ответа, я удалю этот комментарий). В некоторых попытках отладки я подключил контакт A0, с которого я считывал, к земле с резистором 300k между ними и получил довольно значительные (до 20) показания с него, колеблющиеся как волна. Я ожидаю, что это будет 0, что именно измеряется при этом? Я думал, что АЦП не получает напряжения внутри себя, так откуда же берется напряжение? :s предположил, что это связано с «показаниями плавающим контактом», но я все еще в замешательстве., @Beacon of Wierd

@BeaconofWierd, вероятно, ваша схема улавливает электромагнитное излучение, а 300 кОм просто слишком много, чтобы в этом случае заземлить аналоговый штырь. Если вы представите, что увеличиваете это сопротивление, в какой-то момент вы сочтете, что контакт плавает (может быть, на 1 МОм или на 100 МОм?)., @Sim Son

@BeaconofWierd: я согласен с Симом Соном, что сопротивление слишком велико. Согласно техническому описанию, на АЦП должно подаваться измеряемое напряжение от источника с внутренним сопротивлением не более 10 кОм ., @Edgar Bonet