Найти в Дзене
За_тех_кто_в_коде();

С какой скоростью дергаем ножкой?

В некотором продолжении предыдущей темы. Решил проверить с какой же реальной частотой переключаются пины. Свел все в небольшую табличку и как обычно после разного рода замеров я оказался сильно озадачен… Замеры проводил мультиметром в режиме измерения частоты. В пунктах 1-3 заполнение было 48.6-49%, в остальных пунктах 49.9%. Думаю это особенность работы мультиметра. В loop всегда только содержимое одного из пунктов. Первая странность, это то что скорость в Нано значительно отличается от Меги. 328-е я проверял две. Одна UNO которая в DIP корпусе, и второя обычная Нано. Между собой показания не отличались. Ну и в целом, скорость оказалась значительно ниже чем я ожидал. При непосредственном управлении пинами, я предполагал, что скорость не в 2 раза ниже тактовой (это максимальный результат который выдает на ШИМ выходе только счетчик) но в 3-3.5. Ну может 4-5МГц… А тут 1.3МГц. 1-2. функции из Arduino IDE. В первом варианте в области глобальных переменных создается байтовая переменная,

В некотором продолжении предыдущей темы. Решил проверить с какой же реальной частотой переключаются пины. Свел все в небольшую табличку и как обычно после разного рода замеров я оказался сильно озадачен… Замеры проводил мультиметром в режиме измерения частоты. В пунктах 1-3 заполнение было 48.6-49%, в остальных пунктах 49.9%. Думаю это особенность работы мультиметра.

В loop всегда только содержимое одного из пунктов.

Первая странность, это то что скорость в Нано значительно отличается от Меги. 328-е я проверял две. Одна UNO которая в DIP корпусе, и второя обычная Нано. Между собой показания не отличались.

Ну и в целом, скорость оказалась значительно ниже чем я ожидал. При непосредственном управлении пинами, я предполагал, что скорость не в 2 раза ниже тактовой (это максимальный результат который выдает на ШИМ выходе только счетчик) но в 3-3.5. Ну может 4-5МГц… А тут 1.3МГц.

1-2. функции из Arduino IDE. В первом варианте в области глобальных переменных создается байтовая переменная, но с указанием volatile и инициализируется значением «8». Это чтобы при исполнении кода она гарантирована подгружалась из ОЗУ или регистров. Но разница в скорости получилась не очень большая. Я же ранее сталкивался с подобной ситуацией и разница была куда более значимой. Замеры я тогда не проводил, но визуально отличалось на треть или четверть. Именно поэтому при подключении дисплеев нет вариантов выбора пинов в Setup-функции, только правкой в заголовочнике. Ибо скорость садиться. Это к тому что вариант делать #define определения с номером пина в начале скетча, остается и наглядным и более скоростным, как часто делается в скетчах-примерах. Операции с константными значениями выполняются быстрее чем с переменными, тут ничего удивительного нет.

3. Это вариант моих функций, которые я писал в прошлой статье и примере. прошлой статье. Мои — это условно, они очень простые, тут нельзя претендовать на оригинальность. Но я не думал что у них будет столь значительный отрыв от Ардуиновских.

4. Это самый ходовой и рабочий вариант. Вид команды очень простой. Читается как установить единицу в позицию 5.

5. Это ради интереса решил проверить, если в порт заряжаем сразу все значение.

6-7. Далее я решил попробовать взять что-то потяжелее. Использовать красоту и мощь ассемблера! Но с красотой не получилось, из скетча компилятор не видит определений PORTH и прочих, нужно включать заголовочник типа avr/io.h только для ассемблера. Пришлось обращаться к порту по адресу. Для меги не проверял, там выяснять адрес порта... Для пункта 7, в r16 и к17 в блоке Setup были загружены значения 255 и 0. Совпадения по частоте с пунктами 4 и 5 тут не случайны. Строки являются как-бы взаимными копиями. Это я проверял, когда записал все в Atmel Studio и посмотрел что получается на выходе. С одной стороны это тот случай, когда ассемблерные вставки оказались абсолютно бесполезными. С другой стороны, многие толковали что в Си нет команды для прямого обращения к биту как ассемблерные Set bit и Сlear bit. Дык вот же она PORT |= (1<<4); Она же будет идентична PORT |= 0b00010000; Это видимо потому, что все действия с константами проводятся еще до компиляции. В ассемблере есть команды которых явно нет в Си, это например смена местами тетрад байта. Но я не удивлюсь, если окажется, что какой-то код, пусть даже из пары или более строк, который компилятором будет гарантировано и точно заменен на команду смены тетрад.

Не так сложно написать программу на ассемблере, как сложно написать лучше компилятора Си :)