Как менять в arduino ide частоту процессора
Перейти к содержимому

Как менять в arduino ide частоту процессора

  • автор:

Температура процессора и видеокарты, их частота и загруженность.

Сегодня я расскажу как посмотреть основные параметры ПК — это название и температуру процессора и видеокарты. Выведем эти и другие значения при помощи Ардуино на LCD дисплей. Рассмотрим скетч вывода температуры процессора на экран LCD 1602.
Всем привет.
Сегодня продолжим тему о связи Ардуино с вашим компьютером и получим основные характеристики компьютера. Я считаю, что главное в работе компьютера – это его процессор и видеокарта, а точнее их загруженность и температура. Конечно есть ещё память и жёсткие диски, но это оставим для следующей темы. А сегодня процессор и видеокарта.
Для получения данных нам понадобятся любая Ардуина и LCD дисплей, тоже абсолютно любой, я использовал LCD 1602 с I2C подключением. Мне кажется, что это самый лёгкий для повторения пример. Подключить всего 4 провода, два из которых питание и на экране появятся название и параметры ваших процессора и видеокарты, и всё это в реальном времени.
Для работы надо запустить программу которая будет посылать в порт Ардуино эти данные и вам останется просто получить их и вывести на экран дисплея.
Мы будем получать.

  • Фирму производителя процессора и видеокарты
  • Рабочую температуру в реальном времени.
  • Тактовую частоту и их загруженность.

Есть ещё множество параметров которые можно получить. Например все данные о материнской плате, и вентиляторах установленных на ней. Размер памяти ОЗУ и её загруженность, полную информацию о жёстких дисках, но так как мне сейчас это не нужно, да и выводить на этот экранчик неудобно, поэтому я оставил это на будущее. Пишите в комментариях если вам интересна эта тема и какие параметры вы бы хотели увидеть в следующем видео.

Теперь приступим к разбору урока.

Есть много программ для отслеживания параметров компьютера. Вот одна из них. Это программа Open HardWare Monitor.
Давайте её скачаем и посмотрим что она нам покажет, а потом посмотрим, что у нас будет на дисплее.
Переходим по этой ссылке или можно скачать последнюю на текущим момент версию программы по ссылке на моём сайте. Там же будут дополнительные программы и скетч для вывода параметров на дисплей.
Нажимаем Скачать и скачиваем вот эту версию. Теперь переходим в то место куда скачал и запускаем программу.
Для отображения подробной информации о каждом из пунктов раскройте его.

  • Voltages – напряжение (процессора);
  • Temperatures – температуры использования компонента;
  • Fans – скорость вращения вентилятора;
  • Controls – настройка скорости вращения вентилятора вручную;
  • Clocks – тактовая частота работы ядер процессора и видеокарты;
  • Load – степень загрузки компонента;
  • Data – степень физического использование памяти (загрузка ОЗУ и заполнение HDD).

Эти данные постоянно изменяются, так как замеры идут в реальном времени, и чем больше или меньше нагрузка на процессор или видеокарту, тем выше или ниже будет температура. Вот эти параметры мы и будем сегодня считывать.

Загружаем скетч и смотрим что у нас на дисплее. Сначала Ардуина ждёт подключения к серийному порту компьютера. Для того чтобы соединение произошло надо запустить программу Arduino PC Monitor.
Эту программу написал не я. Я позаимствовал её из сети. Ссылка откуда я её взял будет в описании.
Выбираем порт к которому подключена Ардуина.
У меня это COM PORT 4. Так же здесь можно отметить с какой частотой будут производиться вывод на дисплей Можно выбрать от 1 до 5 секунд.
Нажимаем Соединиться и видим, что на экране появилась информация.
Давайте теперь сравним её с программой.
Помимо HardWare Monitor я ещё вывел на экран Диспетчер задач и открыл в нём вкладку Центральный процессор. Так же здесь есть вкладка Видеокарта и там также можно видеть все изменения.
Теперь я заморожу видео чтобы рассмотреть показания.
Мы видим, что у меня процессов компании Intel, i7 3 поколения и модели 820.
Температура в данный момент поднималась до 53 градусов. Это вполне нормальная температура для процессора. Режимы работы своего процессора вы можете найти в даташитах в интернете.
Тактовая частота процессора равна 3703 Мгц . Это количество тактов (вычислений) в секунду. 1 МГц равен 1 миллиону тактов в секунду.
Загруженность процессора 25 %. Показания немного рознятся – это из-за того что я мог неправильно синхронизировать несколько видео. Видео с камеры и скрин с экрана.
Теперь рассмотрим видеокарту. Здесь я особо рассказывать не буду, так как здесь тоже самое что и в процессоре. Мы видим название моей карты. Это NVideo geforce GTX 1650, которая сейчас разогрета до 33 градусов и загружена всего на 3 %, хотя я сейчас снимаю и монтирую видео.

К чему я всё это веду и для чего это может пригодиться.
Ну во первых для любителей разгона. Вы всегда можете в реальном времени видеть какая у вас температура процессора, а добавив в скетч несколько строчек кода вы можете автоматически или вручную включать дополнительный вентилятор или другое охлаждение. Конечно с таким дисплеем смотрится не очень красиво, поэтому я заказал несколько OLED графических дисплеев на которых можно будет построить график и выводить картинки и цвета. Например при превышении заданной температуры на экранчике будет показан сигнал тревоги, а можно и поставить пищалку и подавать звуковой сигнал. Это будет сделать совсем не сложно, и как приедут дисплеи могу сделать такой пример, конечно если будут желающие посмотреть.
Теперь разорвём соединение и перейдём к рассмотрению кода. Для разрыва соединения нажимаем на красный квадратик и видим на дисплее текст disconnect.

Для начала вам надо установить библиотеку LiquidCristal I2C. Её можно скачать из менеджера библиотек программы Arduino IDE.
Для всех любителей писать что в скетче ошибка, теперь буду специально говорить, что у вас может быть другой адрес не такой а например вот такой или другой. Узнать его можно запустив сканер I2C шины.
Остальное стандартное подключение и вывод текста что Ожидается соединение, ждите.
Этот текст пропадёт после того как вы запустите программу Arduino PC Monitor и она соединится с Ардуино по COM порту.
Этот код проверят пришли ли новые сообщения в порт и если да то выводит их на экран.
Выводим на первой строчке CPU если это процессор или GPU если это видеокарта.
Выводим температуру и знак градуса.
На второй строчке выводим частоту и значение мГц.
Ну и дальше выводим загруженность в процентах.
Вот и всё осталось посмотреть схему соединения и можно идти собирать. Схема очень простая. Это простое подключение дисплея по шине I2C. Ждите продолжения. Вывод на графический дисплей и больше данных.

Союз Arduino и классического процессора

Ретрокомпьютерщики бывают различной степени привередливости. Одни довольствуются эмуляцией. Другие предпочитают ПЛИС, потому что тогда получается не эмуляция, а воссоздание. Наконец, третьим подавай настоящий процессор.

Но процессору для работы нужно столько всего! Снова дилемма: взять настоящие микросхемы тех же лет, или поместить всё в ПЛИС, оставив снаружи процессор? Впрочем, почему обязательно ПЛИС? Да здравствует союз Arduino и классического процессора!

Подарите своему Arduino «второй мозг» и сделайте его «умнее».

Настоящий восьмибитный микропроцессор выполняет программы, а Arduino эмулирует ПЗУ, ОЗУ и простейшую периферию.

Проектируйте виртуальную периферию в Arduino IDE, а на микропроцессоре запускайте код на ассемблере. Не нужно собирать сложные схемы и прошивать параллельные ПЗУ.

Поддерживаемые микропроцессоры: 6502, 6809 и Z80 (КР1858ВМ1), на подходе — другие.

Шилд с микропроцессором не мешает подключать другие шилды: с ЖКИ, картами памяти, и др.

Помимо самостоятельного программирования на ассемблере, можно попробовать запустить на микропроцессоре какой-нибудь классический код.

Правда, микропроцессор будет работать на очень небольшой частоте — порядка 95 кГц, точное её значение зависит от оптимизации кода эмуляции периферии.

Распределение адресного пространства задаётся программно в скетче. Микропроцессору можно выделить от 4 до 6 кБ ОЗУ из 8 кБ, имеющихся на Arduino Mega. ПЗУ можно выделить более 200 кБ из имеющихся 256.

При помощи последовательного порта Arduino Mega можно эмулировать UART.

Схемы, чертежи плат, Gerber-файлы доступны под CC-BY-SA 4.0 здесь. При этом имеется требование обязательно прикладывать файл README.md, потому что в нём содержится следующее предупреждение:

Не подключайте шилд, пока не залит скетч эмуляции периферии! Иначе возможно закорачивание выходных линий микропроцессора.

Да и в самом скетче что-нибудь переделывать нужно осторожно по той же причине.

Схема устройства на 6502:

Схема устройства на 6809:

Схема устройства на Z80:

Уже можно запустить:

На устройстве с Z80 — пока только эхо-тест последовательного порта, позволяющий проверить работоспособность виртуального 8251 (КР580ВВ51А).

Прошивки для эмуляции периферии — под лицензией MIT.

Краткие описания принципа действия:

К устройству на Z80 — в процессе подготовки.

Разработчик пытается продавать устройства, но с доставкой только по США. Особого смысла покупать нет, поскольку схема очень простая, повторить её на куске макетки можно за час.

Запланирована разработка аналогичных плат на RCA1802, 68008, 8085 (КР1821ВМ85А), 8088 (КР1810ВМ88). Про К1801ВМ1 не сказано, но можно подкинуть автору такую идею.

Рассмотрим взаимодействие Arduino и устройства на 6502. Arduino периодически меняет уровень на входе микропроцессора, предназначенном для подачи тактовых импульсов, с нуля на единицу и обратно. На каждом такте оно проверяет, что происходит на линиях управления и шине адреса, и, в зависимости от ситуации, считывает информацию с шины данных или отправляет её туда. Arduino может также управлять линиями IRQ и NMI, вызывая прерывания. На рисунке показаны виды данных и направления их передачи:

Соответствие портов Arduino и выводов микропроцессора сконфигурировано в скетче:

/* Digital Pin Assignments */ #define DATA_OUT PORTL #define DATA_IN PINL #define ADDR_H PINC #define ADDR_L PINA #define ADDR ((unsigned int) (ADDR_H 

Разобьём каждый такт на следующие события:

CLK меняет состояние с единицы на нуль (спад)
CLK находится в состоянии нуля
CLK меняет состояние с единицы на нуль (нарастание)
CLK находится в состоянии единицы
CLK снова меняет состояние с единицы на нуль…

Что происходит в моменты смены состояний?

6502 получает тактовые импульсы по входу CLK0, буферизует их и отправляет на два выхода: CLK1 и CLK2. Хотя в микропроцессоре все события привязаны к CLK1, будем считать, что задержка невелика, и они привязаны к CLK0 — той линии, по которой здесь микропроцессор получает тактовые импульсы из Arduino. И называть сигнал просто CLK.

1. CLK меняет состояние с единицы на нуль.

2. Микропроцессор выводит на шину адреса новый адрес, а на выход R/W — сигнал переключения между чтением и записью. Но он ещё не готов к обмену данными.

3. CLK переходит в состояние единицы, и это означает, что обмен данными начался. Если это операция чтения, микропроцессор переводит выводы шины данных в состояние входов и принимает по рим данные, а если операция записи — переводит их в состояние выходов и отправляет данные. А сигнал R/W переключает внешнее устройство в режим записи или чтения, противоположный соответствующему состоянию микропроцессора.

4. CLK переходит в состояние нуля. Теперь на шину даннных ничего не выводят ни микропроцессор, ни устройства ввода-вывода. Микропроцессор может установить в новое состояние линии шины данных и вывод R/W.

Простое объяснение, понятное и ребёнку. Который никогда и не задумается об этих «закулисных интригах», если будет программировать только микроконтроллеры. Даже на ассемблере.

Если нужно подключить своё периферийное устройство, оно должно успевать подготавливать данные до того, как на линии CLK появится единица (время подготовки), а пока там единица — не менять их. Если периферийное устройство не успеет подготовить данные, пока на CLK нуль, или поменяет их, когда там единица, вы будете долго недоумевать, почему ваш код не работает. Поскольку тактовая частота микропроцессора здесь в десять-пятнадцать раз ниже номинальной, соблюсти это требование просто. Но нужно обязательно.

Итак, нужно «научить» Arduino генерировать тактовые импульсы, непрерывно проверяя, что при этом происходит на шине адреса и линии R/W, и соответствующим образом взаимодействуя с шиной данных. Для этого в скетче задействовано прерывание по таймеру timer1, вырабатывающему импульсы с частотой в 95 кГц. Arduino работает значительно быстрее микропроцессора, и потому между его тактами успевает всё и считывать, и подготавливать. Важно проследить, чтобы после модификации скетча это условие продолжало соблюдаться.

Вот выдержка из скетча, по которой понятно, как CLK переходит из нуля в единицу, и что происходит далее:

//////////////////////////////////////////////////////////////////// // Processor Control Loop //////////////////////////////////////////////////////////////////// // This is where the action is. // it reads processor control signals and acts accordingly. // ISR(TIMER1_COMPA_vect) < // Drive CLK high CLK_E_HIGH; // Let's capture the ADDR bus uP_ADDR = ADDR; if (STATE_RW_N) ////////////////////////////////////////////////////////////////// // HIGH = READ transaction < // uP wants to read so Arduino to drive databus to uP: DATA_DIR = DIR_OUT; // Check what device uP_ADDR corresponds to: // ROM? if ( (ROM_START else // KBDCR? if (uP_ADDR == KBDCR) < . // handle KBDCR register >else // DSP? if (uP_ADDR == DSP) < . // handle DSP register >else // DSPCR? if (uP_ADDR == DSPCR) < . // handle DSPCR register >> > else ////////////////////////////////////////////////////////////////// // R/W = LOW = WRITE < // RAM? if ( (uP_ADDR else // KBDCR? if (uP_ADDR == KBDCR) < . // handle KBDCR register >else // DSP? if (uP_ADDR == DSP) < . // handle DSP register >else // DSPCR? if (uP_ADDR == DSPCR) < . // handle DSPCR register >> > //////////////////////////////////////////////////////////////// // We are done with this cycle. // one full cycle complete clock_cycle_count ++; // start next cycle CLK_E_LOW; // If Arduino was driving the bus, no need anymore. // natural delay for DATA Hold time after CLK goes low (t_HR) DATA_DIR = DIR_IN; >

Распределение адресного пространства можно сделать каким угодно, в немодифицированном скетче оно такое же, как в Apple 1 с 256 байтами ПЗУ, 8 килобайтами ПЗУ для Бейсика, 4 килобайтами ОЗУ и устройством ввода-вывода 6821.

// MEMORY LAYOUT // 4K MEMORY #define RAM_START 0x0000 #define RAM_END 0x0FFF byte RAM[RAM_END-RAM_START+1]; // ROMs (Monitor + Basic) #define ROM_START 0xFF00 #define ROM_END 0xFFFF #define BASIC_START 0xE000 #define BASIC_END 0xEFFF //////////////////////////////////////////////////////////////////// // Woz Monitor Code //////////////////////////////////////////////////////////////////// // PROGMEM const unsigned char rom_bin[] = < 0xd8, 0x58, 0xa0, 0x7f, 0x8c, 0x12, 0xd0, 0xa9, 0xa7, 0x8d, 0x11, 0xd0, . 0x00, 0xff, 0x00, 0x00 >; // BASIC ROM starts at E000 PROGMEM const unsigned char basic_bin[] = < 0x4C, 0xB0, 0xE2, 0xAD, 0x11, 0xD0, 0x10, 0xFB, . 0xE0, 0x80, 0xD0, 0x01, 0x88, 0x4C, 0x0C, 0xE0 >;

ОЗУ эмулируется массивом byte RAM[RAM_END-RAM_START+1]. Два ключевых слова PROGMEM нужны, чтобы содержимое эмулируемых ПЗУ хранилось во флеш-памяти микроконтроллера.

6821 эмулирован в достаточной мере, чтобы через «терминалку» работали виртуальные клавиатура и дисплей. Woz Monitor и Бейсик работают, чего и добивался автор.

Чтобы эмулировать любое периферийное устройство, нужно внимательно ознакомиться с его даташитом и выяснить, какие у него есть регистры, и для чего они предназначены. Удобство эмуляции — в гибкости, с которой можно делать программные аналоги периферии.

Устройства ввода-вывода находятся в адресном пространестве микропроцессора, обращение к ним происходит так же, как к ячейкам памяти. Чтобы использовать «железную» периферию, такую, как ЖК-дисплей, карту памяти, выход звука, нужно выделить им в адресном пространстве место.

Переходим к 6809, в нём имеются:

Два восьмибитных аккумулятора A и B, которые могут быть объединены в один шестрадцатиразрядный аккумулятор
Два 16-битных индексных указателя стека
Адресация относительно счётчика команд
Автоматическое прибавление или вычитание числа 1 или 2
Перемножение двух восьмиразрядных чисел без знака
16-битная арифметика
Перенос и обмен данными между всеми регистрами
Запись и чтение всех регистров и любого их сочетания

Микропроцессору 6809E (external) нужен внешний тактовый генератор, у 6809 он внутренний. У Hitachi они называются, соответственно, 6309E и 6309, от обычных они отличаются тем, что внутри операции у них выполняются в 32-разрядном виде, но возможно переключение в режим совместимости с классическим вариантом.

Собственно, весь проект RetroShield потому и начался, что автор хотел модернизировать свой же самодельный компьютер Simon6809 и назвать результат Simon6809 Turbo. Но оказалось, что микросхем стандартной логики для всего, что он хотел там реализовать, потребовалось бы очень много. Поэтому идею RetroShield автор впервые сформулировал именно применительно к 6809, и лишь затем подумал: «а что если и с другими процессорами то же проделать?».

В устройстве, разумеется, применён 6809E, требующий внешнего тактового генератора, чтобы можно было синхронизировать его работу извне. Линии E и Q у обоих процессоров называются одинаково, только у 6809 это выходы, а у 6809E — входы.

С 6809 Arduino взаимодействует так же, как с 6502, но входов тактовой частоты у него два: E и Q, а входов для прерываний — три: IRQ, FIRQ и NMI.

В этот раз соответствие портов Arduino и выводов микропроцессора сконфигурировано так:

/* Digital Pin Assignments */ #define DATA_OUT PORTL #define DATA_IN PINL #define ADDR_H PINC #define ADDR_L PINA #define ADDR ((unsigned int) (ADDR_H 

Как видно из графиков, сигнал Q сдвинут относительно E на четверть периода:

Обращать внимание на Q мы почти не будем, так как все события привязаны к E. А происходит всё так:

  1. E переключается в нуль. Процессор выставляет на шину адреса новый адрес и меняет состояние линии R/W.
  2. E переключается в единицу, процессор становится готов к обмену данными.
  3. Неважно, что происходит с шиной данных, пока на E единица, главное, чтобы требуемые данные там присутствовали в момент перехода E обратно в нуль.
  4. При чтении данных устройство ввода-вывод должно подать на шину данных требуемые данные до перехода линии E из единицы в нуль (минимальная задержка показана числом 17 в кружке).
  5. При записи устройство ввода-вывода должно зафиксировать данные у себя в каком-нибудь регистре в том виде, в каком они были в момент перехода E из единицы в нуль. Процессор же подаст эти данные на шине даже раньше — в момент перехода Q в единицу (число 20 в кружке).
  6. После перехода E в нуль всё повторяется.

Генерация сигналов E и Q, как и в случае с 6502, с той лишь разницей, что сигналов два, и переключать их надо в соответствии с графиками. И точно так же подпрограмма, вызываемая по прерыванию, выполняет в требуемые моменты ввод или вывод данных.

Адресное пространство в немодифицированном скетче распределено так же, как в самодельном компьютере Simon6809:

// MEMORY #define RAM_START 0x0000 #define RAM_END 0x0FFF #define ROM_START 0xE000 #define ROM_END 0xFFFF byte RAM[RAM_END-RAM_START+1]; //////////////////////////////////////////////////////////////////// // Monitor Code //////////////////////////////////////////////////////////////////// // static const unsigned char PROGMEM const unsigned char simon09_bin[] = < 0x1a, 0xff, 0x4f, 0x1f, 0x8b, 0x0f, 0x36, 0x7f, 0x01, 0xa5, 0x10, 0xce, . 0x00, 0x09, 0x00, 0x0c, 0x00, 0x0f, 0xe0, 0x00 >;

ОЗУ и ПЗУ хранятся в массивах так же как в варианте на 6502, с той лишь разницей, что здесь массив с данными ПЗУ — один.

Устройствам ввода-вывода здесь также выделены участки адресного пространства, и они могут быть как виртуальными, так и реальными. Так как Simon6809 — современная машина на винтажной элементной базе, с ПК, на котором запущена «терминалка», она обменивается данными через FTDI. Здесь эмулировано и это.

Rukovodstvo

статьи и идеи для разработчиков программного обеспечения и веб-разработчиков.

Ускорение Arduino

Введение Для многих из нас мы начали программировать на настольных компьютерах и серверах, которые, казалось, обладали бесконечной памятью и вычислительной мощностью (ну, я полагаю, в зависимости от того, когда вы начали программировать). Не было особых причин для оптимизации вашего кода, поскольку в любом случае вы вряд ли превысите ограничения системы. А потом, когда вы занялись встраиваемыми системами, было грубое пробуждение. Переход от такой мощной системы к гораздо меньшей и менее способной, такой как Arduino [/ arduino-separated /], был

Время чтения: 8 мин.

Вступление

Для многих из нас мы начали программировать на настольных компьютерах и серверах, которые, казалось, обладали бесконечной памятью и вычислительной мощностью (ну, я полагаю, в зависимости от того, когда вы начали программировать). Не было особых причин для оптимизации вашего кода, поскольку в любом случае вы вряд ли превысите ограничения системы. А потом, когда вы занялись встраиваемыми системами, было грубое пробуждение. Переход от такой мощной системы к гораздо меньшей и менее производительной, такой как Arduino , был шоком. Внезапно вам пришлось подумать об экономии циклов процессора и памяти, что не всегда легко дается программистам, только начинающим.

Как вы увидите в этой статье, быстрый код важен не только для выполнения вычислений, но даже в большей степени для операций ввода-вывода. Если вы решитесь заняться робототехникой (например, дронами или другими системами управления), это станет еще более очевидным, поскольку большая часть работы, выполняемой микроконтроллером, приводит к вводу-выводу. Обычно более быстрый цикл обратной связи означал лучшую производительность.

После нескольких недель споров с микроконтроллером, чтобы выжать максимум вычислительной мощности для контроллера полета дрона, я подумал, что напишу статью, чтобы помочь вам найти способы повысить скорость и эффективность ваших собственных проектов.

В этой статье я сосредоточусь на Arduino Uno, поскольку это, кажется, самая распространенная плата, хотя большая часть этой статьи также должна относиться и к другим платам.

Почему Arduinos медленные

Тактовая частота

Прежде всего, вы работаете так же быстро, как ваши часы (без учета многоядерных процессоров), которые Arduino Uno по умолчанию использует кристалл с частотой 16 МГц. Это означает, что микроконтроллер ATmega может выполнять до 16 миллионов инструкций в секунду. 16 миллионов инструкций в секунду могут показаться большим количеством (и так оно и есть), но если учесть, что все, что нужно Arduino для выполнения даже простых операций, на самом деле не так уж и много. Для многих проектов тактовые циклы распределяются между такими вещами, как вычисления, связь I2C, чтение и запись на контакты и регистры, а также многие другие операции.

Даже тогда, казалось бы, простые команды могут занять довольно много тактов, например, установка цифрового вывода на высокий уровень. Это одна из простейших операций ввода-вывода, которые вы можете выполнить на Arduino, но на самом деле она занимает очень много времени (более 50 тактов!) Из-за количества кода, используемого в digitalWrite() , который я рассмотрю в следующий раздел. Таким образом, более быстрые часы позволят вам выполнять инструкции в более быстром темпе.

Проверки безопасности и валидация

Так почему же Arduinos медленные, если не считать тактовой частоты? Что ж, в основном это связано с некоторыми стандартными вызовами методов и объектами, которые мы используем в нашем коде. Вот лишь несколько основных виновников:

  • digitalWrite()
  • digitalRead()
  • pinMode()

Многие из этих методов страдают теми же недостатками, поэтому давайте взглянем на код одного из наиболее часто используемых методов, digitalWrite() :

 void digitalWrite(uint8_t pin, uint8_t val) < uint8_t timer = digitalPinToTimer(pin); uint8_t bit = digitalPinToBitMask(pin); uint8_t port = digitalPinToPort(pin); volatile uint8_t *out; if (port == NOT_A_PIN) return; // If the pin that support PWM output, we need to turn it off // before doing a digital write. if (timer != NOT_ON_TIMER) turnOffPWM(timer); out = portOutputRegister(port); uint8_t oldSREG = SREG; cli(); if (val == LOW) < *out &= ~bit; >else < *out |= bit; >SREG = oldSREG; > 

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

Первые несколько строк используют pin чтобы найти соответствующий timer , bit и port для данного вывода. На port - это просто регистр с отображением памяти, который управляет несколькими выводами. Чтобы включить или выключить только тот вывод, который нам нужен, нам нужно определить, какому биту регистра соответствует наш вывод, что и делает функция digitalPinToBitMask()

Найдя timer , bit и port , мы проверяем, действительно ли это правильный контакт. Эта строка не требуется для функции digitalWrite() для выполнения своей работы, но она действует как подстраховка для более неопытных программистов (и даже для опытных). Мы бы очень не хотели, чтобы запись в неправильный адрес памяти приводила к повреждению программы.

if (timer != NOT_ON_TIMER) . предназначена для того, чтобы убедиться, что мы завершили любое предыдущее использование вывода ШИМ перед записью «постоянного» высокого или низкого уровня. Многие выводы на Arduinos также могут использоваться для вывода ШИМ, для чего требуется таймер для работы, отсчитывая рабочие циклы. При необходимости эта строка отключит ШИМ. И снова, чтобы убедиться, что мы не видим странного поведения, это проверка безопасности, призванная помочь пользователю.

И, наконец, в последних нескольких строках мы фактически устанавливаем заданное значение для данного порта.

Проверки безопасности немного замедляют выполнение, но также значительно упрощают отладку. Таким образом, когда что-то пойдет не так, у вас меньше шансов получить странное поведение, которое заставит вас чесать голову. Нет ничего более неприятного, если иметь, казалось бы, логичный код и не получить ожидаемого результата. Программирование микроконтроллеров сильно отличается от программирования настольных или телефонных приложений (хотя и с ними тоже есть свои трудности). Поскольку вы работаете напрямую с оборудованием и у вас нет операционной системы, которая обеспечивала бы вашу безопасность, проблемы может быть трудно найти.

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

Вы также должны знать, что вызовы методов не всегда медленные из-за количества выполняемого кода, но способствующий фактор может быть из-за физических ограничений устройства. Например, analogRead() занимает около 100 микросекунд на вызов из-за предоставляемого разрешения и тактовой частоты. Более низкое разрешение АЦП уменьшит время каждого вызова. Однако даже тогда, хотя аппаратное обеспечение в конечном итоге является здесь ограничивающим фактором, код Arduino консервативно устанавливает максимальную частоту дискретизации АЦП только на 9600 Гц (в то время как поддерживает около 77 кГц). Итак, хотя Arduinos намного медленнее, чем они должны быть, это не всегда из-за выбора дизайна и компромиссов. Существует хорошее обсуждение об этом здесь , и документация здесь .

Как ускорить Arduino

Чтобы было ясно, мы на самом деле не делаем Arduino быстрее , скорее, мы делаем код более эффективным . Я указываю на это различие, потому что использование этих уловок не даст нам более быстрых часов (хотя мы можем ускорить их, о чем я коснусь позже), они просто будут выполнять меньше кода. Это важное различие, потому что более быстрые часы дают нам другие преимущества, такие как наличие более точных таймеров, более быстрое общение и т. Д.

Также имейте в виду, что, используя приведенный ниже код, вы делаете некоторые компромиссы. Программисты, разработавшие Arduino, были не просто паршивыми кодировщиками, которые не могли писать быстрый код, они сознательно приняли решение добавить проверки и проверки безопасности к таким методам, как digitalWrite() поскольку это приносит пользу их целевым клиентам. Просто убедитесь, что вы понимаете, что может (и будет ) пойти не так, как надо.

Во всяком случае, перейдем к коду.

Цифровая запись

Сейчас я не собираюсь показывать вам, как ускорить каждый метод, но многие из тех же концепций, pinMode() . Минимальный объем кода, который вам нужно записать на пин, составляет:

 #define CLR(x,y) (x&=(~(1< 

Как видите, в этих макросах мы переходим к сути. Чтобы использовать их, вам придется напрямую ссылаться как на порт, так и на битовую позицию, вместо удобного использования номеров контактов. Например, мы могли бы использовать такой макрос:

 SET(PORTB, 0); 

Это приведет к записи HIGH значения на вывод 8 на вашем Arduino Uno. Это немного грубо, но намного быстрее. Это также означает, что мы более склонны делать что-то неправильно, например, ссылаться на несуществующий порт, писать поверх активного ШИМ или делать многое другое.

Макрос дает нам значительный импульс, используя примерно 2 цикла (частота 8 МГц), тогда как digitalWrite() использует колоссальные 56 циклов (частота 285 кГц).

Серийный

К сожалению, для некоторых задач, например, если вам нужно использовать последовательную связь, вы не так много можете сделать, чтобы улучшить скорость, но есть некоторые оптимизации, на которые вы можете обратить внимание.

Последовательная связь обычно используется для отправки отладочной информации или информации о состоянии в настольную среду IDE, что означает, что у вас, вероятно, есть Serial.println() во всем вашем коде. Об этих операторах легко забыть после разработки, поэтому, если вы ищете повышения скорости и больше не нуждаетесь в отладке, попробуйте удалить все println() и полностью удалить Serial из кода. Просто инициализировав его (и даже не используя Serial.println() ), вы тратите много циклов на прерывания TX и RX. В одном случае , это было измерено , что только с Serial включенным замедлились в digitalWrite() š примерно на 18%. Это много потраченных впустую циклов из-за мертвого кода.

Тактовая частота

Хотя я в основном сосредоточился на улучшениях программного обеспечения, которые вы можете внести, не забывайте, что всегда есть «простое» улучшение - ускорение часов. Я говорю это так, потому что на самом деле это не простое улучшение plug-and-play. Чтобы ускорить часы на Arduino, вам необходимо вставить новый кристалл в плату, что может оказаться сложным, а может и нет, в зависимости от ваших навыков пайки.

После того, как вы установили новый кварцевый генератор, вам все равно нужно обновить загрузчик, чтобы отразить изменения, иначе он не сможет получать код через последовательный порт. И, наконец, вам нужно изменить F_CPU на правильную тактовую частоту. Например, если вы увеличили частоту до 20 МГц (самые быстрые часы, на которые рассчитана ATmega), вам необходимо изменить несколько файлов в среде Arduino IDE:

  • В preferences.txt измените
    • из: build.f_cpu=16000000L
    • кому: build.f_cpu=20000000L
    • из: F_CPU = 16000000
    • к: F_CPU = 20000000

    Согласно этой публикации , ATmega328 можно разогнать до 30 МГц, но я не рекомендую это делать =)

    Заключение

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

    Есть ли какие-нибудь собственные оптимизации, которыми вы хотели бы поделиться? Дайте нам знать об этом в комментариях!

    Не забудьте подписаться на нашу рассылку, чтобы получать наши лучшие статьи прямо в свой почтовый ящик!

    Licensed under CC BY-NC-SA 4.0

    Как правильно установить параметры платы Esp8266 Arduino IDE?

    При выборе платы Nodemcu 1.0 в Arduino Ide появляется еще нескоько параметров, например частота процессора 80 или 160, размер файловой системы (2 варианта по 4 mb), что то еще.
    При выборе Generic esp8266 параметров еще больше.
    Подскажите как их правильно выставлять и где почитать про них, в большинстве руководств пишут ‑ выберите плату и работайте, а про остальные параметры‑ ни слова.

    sasha_ml
    New member

    конкретизирую вопрос
    Частота CPU и частоту флэш можно выбрать любую - какую выберешь, на такой и будет работать - верно?
    Частота кристалла 26 или 40 - тут надо смотреть с лупой? Может какая то частота рапостранена , а другая встречается крайне редко?
    reset metod - ck и nodemcu на что влияет?
    flash mode по какому принципу выбирать?
    flash size надо смотреть на плате? (куда смотреть?) а наличие spiffs выбирать какую хочется?
    IW Ip variant на что влияет?
    debug level если выбрать -чтото будет выдаваться в serial - а что такое serial1?
    upload speed - вкаких случаях можно выбирать скорости типа 921600 ?

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *