Скачет задержка.
- Войдите на сайт для отправки комментариев
Добрый день. Сразу замечу что я не очень разбираюсь в програмирование и, надеюсь, что в этом разделе форума это допускается.
Мой вопрос в следующем. Я решил сделать простенькое устройство, генератор импульсов с задержкой на Arduino nano (китайская копия, если это важно) и что я не пытался делать, задержка, необходимая мне между двумя импульсами всегда скачет в диапазоне около 10мкс. Сначала я пытался сделать это считывая micros() в цикле while(), задержка скакала, я решил, что это возможно из-за случайного времени выполнения всех мат. операций и считываний в цикле, в общем, не буду излагать здесь всю трогательную историю моей борьбы, скажу лишь, что закончил я так
PORTD |=1<<2; asm("nop"); // повторяется сто раз просто скопированная строка asm("nop"); PORTB |=1<<3;
То есть в моём понимание болтаться просто нечему. Но на деле выходит картина приведённая на иллюстрации ниже
Здесь красный первый импульс и жёлтый второй видно, что он бывает в двух разных местах, разница между которыми 6,26 мкс. С более сложными (но более удобными и понятными мне кодами) типа циклов while(t<T){t=micros();...} ,разброс достигает 10 мкс и положения не 2, а больше. Болтанка от абсолютной величины задержки, на мой взгляд, не зависит.
Подскажите, пожалуйста, что я делаю не так.
Спасибо
всё так, так и должно быть, если болтанка критична, переходить на авр студию
Запретить все прерывания. Не запускать никакие библиотеки. И лучше выложить полный код, а не кусочек, который теоретически должен работать корректно.
Код я могу выложить без проблем, но он у меня в отвратительном тестовом виде с кучей процедур не имеющих отношения к делу и, мне кажется, что просто как-то не вежливо его так выкладывать. Но, на всякий случай, я его приложу, но никому смотреть и разбираться в полном коде не советую :-)
Из билиотек я использую
Спасибо, обязательно попробую при случае, но пока это выше моего понимания.
Так у Вас кроме генератора еще столько наворочено. По хорошему диспле и энкодер работают только пр установке параметров генератора, а дальше все это отрубается и запускается генератор. Выход из него только по сбросу. Тогда можно говорить о стабильности.
Запретил прерывания. В приведённом варианте болтанка пропала. С циклом while(){micros();...} всё равно не работает, но, как я понимаю это уже из-за случайности момента считывания micros(); не так удобно, но зделаю цикл for(){nop}, наверное. Больше спасибо за совет. Проблема скорее решена
Запретил прерывания. В приведённом варианте болтанка пропала. С циклом while(){micros();...} всё равно не работает, но, как я понимаю это уже из-за случайности момента считывания micros(); не так удобно, но зделаю цикл for(){nop}, наверное. Больше спасибо за совет. Проблема скорее решена
Успехов!
Спасибо
Запретил прерывания. В приведённом варианте болтанка пропала. С циклом while(){micros();...} всё равно не работает, но, как я понимаю это уже из-за случайности момента считывания micros(); не так удобно, но зделаю цикл for(){nop}, наверное. Больше спасибо за совет. Проблема скорее решена
а микрос работает после запрета прерывания?
Ну, как-то да - работает. Выдаёт примерно похожие на правду результаты. В интернетах пишут, что так делать нельзя, но мне, благо и не подходит по вышеописанным причинам, но когда я сейчас пробовал - работает. Ошибку не выдаёт в плату заливается, плата работает как нужно, но с болтанкой, которую я списываю на сучайность времени считывания.
Болтанки быть не должно, если программа написана правильно. Для выдачи стабильного результата на высоких скоростях надо использовать таймер с прямой выдачей на ногу м.с. В этом случае результат не будет зависить от прерываний и команд внутри цикла loop. В интернете много примеров програмирования таймера. Даже здесь на форуме. Например http://arduino.ru/forum/proekty/generator-s-reguliruemoei-chastotoi-na-arduino
Большое спасибо. Обязательно попробую что-то такое - давно хотел разобраться с таймерами. Сейчас требуемую мне задачу я решил, возможно, конечно, не самым прямым методом, но задержка совершенно стабильна для моих задач и регулируется с точностью, примерно в 1мкс от 20 до 1000. Абсолютное значение задержки и для меня не важно - в основном важна была стабильность.
Если интересно - вот конечный код, который работает
Ещё раз всем большое спасибо за помощь