@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
  • Вопрос задан
  • 111 просмотров
Пригласить эксперта
Ответы на вопрос 1
gbg
@gbg
Баянист. Тамада. Услуги.
Очевидно, что для выполнения Serial.println эта ерундовина тоже использует прерывания -так она подгружает в порт очередной символ после отправки предыдущего.

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

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

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

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

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

Войти через центр авторизации
Похожие вопросы