Точная задержка
- Войдите на сайт для отправки комментариев
Доброго времени суток,
оговорюсь сразу я новичок и пришёл с твёрдым намереньем нервировать матёрую часть бывалых пользователей форума. ;)
Цель:
Настраиваемый 2x-канальный триггер сигнала с временой разницей триггера (задержкой) в районе (1-10 мкс, шаг 1 мкс).
К примеру: На пине D1 (по сигналу кнопки) состояние меняется с 0 на 1, далее в зависимости от выбранной задержки к примеру 2 мкс меняеся состояние с 0 на 1 на пине D2. Через 100-300 миллисекунд состояние на обоих пинах (D1, D2) возвращается снова в состояние 0.
Главная проблемма это задержка. По нижеуказанному скетчу принцип реализуется, но стабильно работает только с 5-6 мкс.
void setup() { pinMode(13,INPUT_PULLUP); // кнопка pinMode(12, OUTPUT); // Trigger ch1 pinMode(11, OUTPUT); // Trigger ch2 } void loop() { if(digitalRead(13)==LOW) { digitalWrite(12, LOW); delayMicroseconds(10); digitalWrite(11, LOW); delay (200); digitalWrite(12, HIGH); digitalWrite(11, HIGH); } }
Для начала использовал Arduino UNO, потом решил взять более шуструю платформу NodeMCU на базе ESP8266. Она отказалась работать по скетчу для ардуино, пришлось немного переписать но на команды delayMicroseconds() в области 1-50 мкс она отказывается реагировать. Минимальная задержка 5 мкс.
void setup() { pinMode(D3, INPUT); // кнопка pinMode(D1, OUTPUT); // Trigger ch1 pinMode(D2, OUTPUT); // Trigger ch2 } void loop() { if(digitalRead(D3)==LOW) { digitalWrite(D1, LOW); delayMicroseconds(4); digitalWrite(D2, LOW); } else { digitalWrite(D1, HIGH); digitalWrite(D2, HIGH); } }
Получается что проблемма в примитивном скетче с большими задержками а так же футкции "delay". Вероятно что micros() тоже не вариант из-за разрешения 4 мкс.
Каким способом можно реализовать стабильнуюб точную задержку на этих платформах в этом временном промежутке (1-10 мкс)?
Заранее спасибо.
Цель: Настраиваемый 2x-канальный триггер ....
Вот здесь не понял. Так, какова же всё-таки цель? Нервировать или триггер сделать?
(я говорю только про ардуино)
Насколько точную? Шаг в 62,5 наносекунд (если считать кварц идеальным) устроит? Если да, то делается просто при помощи таймеров. Если нет - то никаким.
Можно запытать _delay_us(0.5);
Но от digitalWrite() желательно избавиться сразу, если речь зашла о таких интервалах.
Можно запытать _delay_us(0.5);
Фига-се! А я и не знал, что она void _delay_us(double __us). Наверняка, видел когда-то, но прочно забыл :)
Да... но есть проблема - в последний раз, когда я пытался её использовать, она требовала inline указания числа, с переменной не прокатывает. Видимо как-то там, внутрях, разворачивается в NOP-ы при компиляции.
Так само-собой. Вот она
По поводу "нервировать..." это шутка))) В основном новички на форумах хватают вершки, переспрашивают одно и тоже... мало чего понимают в тематике.... чем нервируют более опытных товарищей )))
Шаг в 62,5 нано было бы идеально....
Я был бы более чем доволен погрешностью в +/- 250 нано. )))
Ну, та в путь, всё пишется в три строки. Гуглите "работа с таймерами ардуино" или просто смотрите даташит (что лучше).
Только помните, что это низкоуровневые вещи, т.е. для разных контроллеров (например, для Uno и Mega) это пишется по-разному. Всё равно в три строчки, но по-разному.
Но от digitalWrite() желательно избавиться сразу, если речь зашла о таких интервалах.
Вот тут 10 раз согласен digitalWrite()- очень медленная функция с проверкой всего начиная от динозавров. Пишите прямо в порт.
Угу. Можно попробовать что то типа (с нумерацией мог накосячить)
Число nop подобрать. Если много получается - сунуть в цикл for.
Угу. Можно попробовать что то типа (с нумерацией мог накосячить)
Число nop подобрать. Если много получается - сунуть в цикл for.
Спасибо, большое за конкретный ответ, попробую и отпишусь что получилось.
Доброго временни суток,
сново вернулся к этой теме. По поду работы с таимерами и управлнни портами через регисты проинформировался, но не попрактиковался ))) Как говорится на предложенных примерах всё понятно, а вот самому написать сложновато ))) Но об этом позже, когда будут конкретные вопросы.
Для начала решение от Morroc.
На вскидку прошил Ардуино предложенным скетчем:
работает, очень даже точно. Спасибо за простое решение. Но есть одна несущественная мелоч. Изменение состояния происходит не мгновенно а логарифмически и занимает примерно 3-4 µs. Соединение к осцилографу ни каких поразитных емкостей не имеет.
Для сравнения, изменения состояния по скетчу который я вначале предложил, происходит мгновенно. При этом подключение остаётся тем же.
Простите, т.е. Вы хотите сказать, что изменение состояния пина по команде
"происходит не мгновенно а логарифмически и занимает примерно 3-4 µs", в то время как изменение состояния пина по команде
"происходит мгновенно"?
Простите, но это бред - этого не может быть потому, что этого не может быть никогда. Команда B, внтури кода всё равно исполняет исполняет команду A. Команда A - это шататный метод изменения состояния пина - им пользуются все, в том числе и команда B.
Ищите ошибку в своих измерениях или их интерпретации.
а порты на вывод настроить?
pinMode(11,OUTPUT) или DDRB = (1<<DDRB3)
pinMode(12,OUTPUT) или DDRB = (1<<DDRB4)
или так: DDRB = (1<<DDRB3)|(1<<DDRB4);
Если следовать логике то да, это бред. А если учесть что соединения, настройки осцилографа... я не трогал и просто перезалил скетч то это становится неоспоримым фактом)))
Ищите ошибку. Например, то, о чём сказал коллега постом выше. Нет? Ищите ещё! Где-нибудь
шнурок развязалсяконтакт отпал, что угодно. Но так не бывает.Действиткльно причина была в этом. Нужно было задикларировать модус портов.
Спасибо большое! ;)
Действиткльно причина была в этом. Нужно было задикларировать модус портов.
Спасибо большое! ;)
ну так порты настроены на ввод, если не переключить на вывод, то запись 1 подключает внутренний резистор (аналогично команде pinMode(pin INPUT_PULLUP)), получается интегрирующая цепь, резистор, входная ёмкость осциллографа, оно передний фронт и затягивало ...
)))
Вот выдрал из старого проекта точную задержку.
Понятно, что для точного времени задержки надо запретить прерывания и расчитать времена преамбулы и возврата.