@we1

Почему другие функции вне цикла влияют на время работы AЦП?

Внутри функции проходит тысяча замеров напряжения, чтобы потом вычислить частоту. В этой функции нет никаких выводов и запросов. Но на время delta_time могут влиять другие функции, которые написаны после или вообще вне фукнции analyze(). Например, очень сильное влияние оказывает Serial.print().

void analyze (){
  i = BUFFER_SIZE;

  ADMUX=B11100111;
  delay(10);

  time = micros();

  while (i--)
  {
    ADCSRA=B11000010;   // 1/4
    while (ADCSRA & (1 << ADSC));   // Ожидание флага окончания преобразования
    buffer[ i ] = ADCH;
  }

  delta_time = micros() - time;
}


Очевидно, что во время выполнения опроса срабатывает таймер, который нужен для работы функции micros(). Но его влияние не должно увеличивать полученное время на 20-25 процентов. У меня получается, что если в функции loop() после вызова analyze() сделать несколько вызовов Serial.print(), то время delta_time весьма заметно увеличивается. Хотя я не понимаю как. Отключить таймер нельзя, так как без него я не могу узнать время выполнения цикла опроса АЦП.

Два вопроса:
1) почему Serial.print() и даже простые арифметические выражения "замедляют" опрос АЦП в другом месте программы?
2) как можно посчитать время другим способом, без использования таймера 0 и micros()/millis()?

P.S. Пример кода это слегка модифицированная функция AnRead() из CyberLib.h
  • Вопрос задан
  • 121 просмотр
Пригласить эксперта
Ответы на вопрос 1
gbg
@gbg Куратор тега Arduino
Любые ответы на любые вопросы
Очевидно, что для выполнения Serial.println эта ерундовина тоже использует прерывания -так она подгружает в порт очередной символ после отправки предыдущего.

Как только речь идет об использовании риалтайма, первое, что надо сделать - выкинуть ардуинскую среду к чертовой матери и поставить AVR_Studio.

Там есть нормальный, не заваленный барахлом для начинающих, компилятор GCC и нормальные, не таскающие за собой C++, библиотеки.

Затем, нужно разобраться с таким явлением как прерывания. В даташите на контроллер написано, как настроить АЦП на вызов прерывания по окончании очередного измерения, а также можно написать обработчик этого прерывания на ассемблере. Тогда и функция подсчета числа миллисекунд вам будет не нужна, потому что время выполнения программы вам будет точно известно - его можно посчитать по количеству тактов на измерение АЦП (см. даташит) и количеству инструкций в обработчике прерывания (см даташит еще раз, большинство инструкций контроллер делает ровно за 1 такт). В обработчике нужно быстренько засунуть новый отсчет в массив и свалить.

Насколько я помню, максимальная частота съема, которую можно выжать из АЦП, около 32 кГц при тактировании контроллера от 20МГц
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы