Почему осциллограф показывает более длительный период времени, чем мои наборы кодов?

Итак, я программирую модуль камеры с линейным сканированием TSL1401R-LF , который считывает массив пикселей 1 X 128. У меня возникла проблема с точностью вывода. В основном камера становится менее точной по мере уменьшения времени задержки. Для отладки я подключил его к осциллографу и отслеживал импульсы SI и CLK, отправляемые на часы, а также исходящие от них аналоговые сигналы.

Вот почему я заметил, что продолжительность сигнала CLK составляет более 300 микросекунд. Это странно, потому что мой код устанавливает длительность 170 микросекунд. Поскольку это мой первый электрический проект, я не уверен, что с этим делать, поэтому я надеюсь, что кто-то может взглянуть на мой код и скриншот осциллографа и сообщить мне, естественно ли то, что я вижу, или нет. .

Вот код:

int delayTime = 170;

void timming()
{

  //The timing for the impluses was found through direct experimentation.
  //(Meaing that I played around with different delayTimes until the code worked)

  digitalWriteFast(SI, HIGH);
  delayMicroseconds(delayTime/2);
  digitalWriteFast(CLK, HIGH);
  delayMicroseconds(delayTime/2);
  digitalWriteFast(SI, LOW);
  delayMicroseconds(delayTime/2);
  digitalWriteFast(CLK, LOW);
  delayMicroseconds(delayTime);

  for(int i = 0; i < 129; i++)
  {
    digitalWriteFast(CLK, HIGH);
    delayMicroseconds(delayTime);
    digitalWriteFast(CLK, LOW);
    delayMicroseconds(delayTime);
  }

}

Вот скриншот

введите описание изображения здесь

Желтая линия — это импульс SI, светло-голубая — это импульс CLK, а фиолетовая — аналоговый выход.

Это может быть полезно, особенно если у вас где-то запущены прерывания: arduino : delaymicroseconds() . Я не пользователь Arduino, но вам, вероятно, лучше использовать аппаратный таймер, вызывающий прерывание.
Период тактового импульса кажется разным между импульсами 1-2 и 2-3. Если delaymicroseconds() является программным таймером, то его точность сомнительна в зависимости от того, прерывает ли его что-либо. Как упоминает @Tut, аппаратный таймер обеспечит очень повторяемые часы. AVR имеет несколько вариантов таймера для различных форм сигналов, хотя вам придется согласовать желаемый таймер с вашей проводкой.
@Smith Возможно, центр дисплея отмечает начало выполнения. Тогда это последовательно. SI становится высоким, затем CLK высоким, затем SI низким, затем CLK низким, после чего CLK переключается.
Похоже, что калибровка delayMicrosecondsотключена. Это динамически калибруется? Если это так, вы должны позвонить что-то, чтобы откалибровать его?
как написано, ваш код всегда будет медленнее, вы делаете что-то, что требует времени, затем ждете некоторое время, а затем делаете что-то, что требует времени. вещи между таймингами не совсем бесплатны. Точно так же маршрутизация синхронизации, скорее всего, имеет накладные расходы, поэтому она немного длиннее из-за кода, вызова функции или долей периода времени на любом конце измерения. это не то, как сделать точное время. вы хотите использовать таймер и устранить стоимость кода или усреднить его.
возьмите отметку времени, сделайте то, что вы хотите сделать, ДОБАВЬТЕ (или ВЫЧИТАЙТЕ) К ЭТОЙ ОТМЕТКЕ ВРЕМЕНИ, которую вы взяли, количество времени, которое вы хотите, и / или используйте его в качестве ссылки, не берите новую отметку времени после того, что вы хотели делать. когда таймер дойдет до новой метки времени, повторите.
то, что вы делаете, это то, что часы показывают 8:01, затем вы делаете что-то, что занимает 1 минуту. Затем вы смотрите на часы 8:02 и ждете 5 минут до 8:07, затем делаете что-то, что занимает одну минуту, 8:08 ждете 5, и вы продолжаете накапливать ошибку. Теперь в дополнение к этой ошибке у вас может быть какая-то другая ошибка, которую вы, возможно, ищете с этим билетом.
Есть несколько хороших библиотек Arduino, которые используют прерывания для запланированных событий с точным временем, для выполнения кода требуется время, и после того, как код Arduino скомпилирован для сборки, каждая строка может легко занять десятки инструкций по сборке. Проверьте библиотеку TaskScheduler.

Ответы (1)

Главная проблема

Похоже, что чип работает на более низкой тактовой частоте, чем должен быть. Если delayMicrosecondsпредположить, что тактовая частота составляет 16 МГц, а чип фактически использует, например, внутренний генератор с частотой 8 МГц, длина импульсов удвоится. Вы можете проверить это:

  • Кварцевый генератор работает и работает на правильной частоте
  • Фьюз-биты atmega настроены на использование внешнего генератора.
  • Нет набора предделителей

Также

Функция Arduino delayMicrosecondsне является хорошим способом заставить что-то происходить каждые 85 мкс и digitalWriteне помогает в вашем случае. Если вы углубитесь в определение двух функций (которые предоставлены проектом Arduino, а не компанией Atmel, создавшей реальный микропроцессор), вы увидите, что они на самом деле удивительно сложны. Теперь компилятор значительно упростит их, но даже тогда у вас останется много операций, и эти операции будут удлинять пульс.

Вы можете переписать код, чтобы ускорить процесс, но есть способ получше. Микросхема AVR, используемая в Arduino, имеет несколько таймеров. Они работают параллельно с процессором, который запускает ваш код, и они могут переключать контакты или запускать короткие фрагменты кода через очень точные интервалы. Недостатком является то, что, хотя таймеры являются основной функцией микросхем AVR, они редко используются в мире Arduino. Поэтому вам придется погрузиться в менее удобную для пользователя документацию, чтобы понять, как их использовать.

Это также зависит от конкретной модели Arduino: у меня есть китайский клон Nano, который может выводить (с помощью DigitalWrite) прямоугольную волну 5us + us, указанную в DigitalWrite, как швейцарские часы. Добавленные 5 мкс примерно соответствуют времени, необходимому для выполнения инструкции задержки и записи. С другой стороны, оригинальный Micro, в 10 раз более дорогой, не способен на это, поскольку тайминги повсюду. Возможно, это потому, что он имеет USB, встроенный в микроконтроллер, и он тоже должен обслуживать его. Возможно, в OP следует указать, что использует Arduino.
Я согласен с этим ответом. Отклонение времени почти ровно в два раза указывает на проблему с конфигурацией часов.