faculty_project/Проектирование встроенных приложений Практическая работа 1 _вер.6_.docx

382 KiB
Raw Permalink History

Практическая работа1.

АППАРАТНОЕ И ПРОГРАММНОЕ ОБЕСПЕЧЕНИЕ ПЛАТЫ NODEMCU НА ОСНОВЕ МИКРОКОНТРОЛЛЕРА ESP8266.

Цель работы Знакомство с аппаратным и программным обеспечением платы NodeMCU, блок-схемой взаимодействия платы с персональным компьютером и пользовательской программой, особенностями запуска программ.

ОБЩИЕ СВЕДЕНИЯ

ПлатаNodeMCU на базе микроконтроллера esp8266предназначена для удобного управления различными устройствами при помощи проводных интерфейсов, а также посредством передачи сигнала в локальную сеть или интернет посредством технологии Wi-Fi.

Основные характеристики платы NodeMCU на базе ESP8266:32-битный процессор;поддержка WiFi: 802.11 b/g/n;напряжение питания 3.3 В;интефейсыUSB, UART, SPI, I2C;flash-память 4 Mбайт;возможность обновления прошивки по USB и Wi-Fi;адаптирована для применения с языками программирования С/С++, ASM.

На рис. 1 приведены основные выводы (pinout) для платыNodeMCUv3 (существует несколько версий), с обозначением нумерации выводов, используемой в среде программирования, в которой будет составляться код программы, для дальнейшего исполнения:

NodeMcu-V21-CP2102-Lua-ESP8266-pinout-mischianti-low-resolution

Рис. 1. Нумерация выводов платы NodeMCUv3.

Для создания программ используется среда программированияArduinoIDE.Программы, написанные в среде Arduino, называются наброски или скетчи (транслитерация от англ. sketch) и сохраняются в файлах с расширением *.ino.

Нумерация выводов в среде программирования ArduinoIDE, и обозначения на плате, могут отличаться. Поэтому необходимо в момент инициализации или объявления переменных пинов, сверяться с данной схемой.

Для выполнения пользовательского кода на плате NodeMCUv3, необходимо доставить скомпилированный код из программы разработки ArduinoIDE,функционирующей на персональном компьютере в память микроконтроллера. В момент написания программы в ArduinoIDEразработки код представляет собой текстовый файл. После компиляции преобразования текста кода в машинный код (дополнительную информацию можете найти в источниках: [1], [2] нужно не забыть привести список литеруры), машинный код, готовый для выполнения в микроконтроллере, через интерфейс USBиз персонального компьютера доставляется к преобразователю интерфейсов CH340 (конвертер USB-UART)NodeMCU, после чего по интерфейсу SPI производится последовательная запись программы в flash-память. После перезагрузки ESP8266 счетчик команд сбрасывается, очищается ОЗУ и выполнение программы начинается с нулевого адреса.

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

Рис. 2. Блок-схема взаимодействия по доставки пользовательского кода в память микроконтроллера.

Программа разработки пользовательского кода Arduino IDE, представляет собой оболочку текстового редактора (рис.3), совмещенную со встроенным компилятором GCC, для языка программирования С++. В центральном окне производится написание кода программы, в верхней части расположены стандартные Windows панели, ниже них располагаются дублирующие кнопки функционала панелей загрузка, проверка, сохранить, загрузить, новый скетч. Для загрузки программы в память микроконтроллера не обязательно проверять код нажатием на кнопку «проверить», т.к. перед загрузкой код программы автоматически будет проверен заново.

Для корректной работы программы в коде всегда должны присутствовать С++ функции Setup и Loop. Они являются функциями-обертками над стандартными С функциями Init и main супер-циклом.

  1. СОЗДАНИЕ ПЕРВОГО СКЕТЧА

Для первого скетча, предлагается выполнить написание следующего кода листинг 1 и выполнить программирование микроконтроллера, для выполнения данного пользовательского кода.

void setup() {

pinMode(3, OUTPUT);

digitalWrite(3, 1);

delay(1000);

digitalWrite(3, 0);

}

void loop() {

}

Листинг 1. Код программы управления напряжением на 3 выводе МК.

Основа кода программы состоит из двух функций setup и loop. В функции setup выполняется первичная инициализация, необходимая для работы периферии микроконтроллера и его устройств. Функция setup выполняется один раз после перезагрузки микроконтроллера. Далее выполнение продолжается в циклическом вызове функции loop, от начала блока loop, до его завершения внутри фигурных скобок.

В языке С++ фигурные скобки представляют логическое разбиение кода на блоки, и служат для выделения области видимости. Так каждая из двух функций, представляют свою область видимости для функций и локальных переменных. Для запоминания возможностей использования переменных в языке С++, относительно области видимости, можно воспользоваться следующим выражением: «внутрь можно, наружу нельзя». Переменные объявленные внутри своей области видимости, не могут быть использованы вне области объявления. В то время как переменные из более глобальной внешней области, могут быть использованы внутри локальных областей видимости.

Выполнение программы листинга 1 содержит три команды оболочки Adruino IDE, которые являются С++ функциями надстройками над С командами, командами обращения к регистрам управления микроконтроллера:

pinMode установка необходимого номера вывода в режим входа или выхода;

digitalWrite установка для вывода, работающего на выход, указанного логического состояния;

delay задержка выполнения на указанное количество мс;

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

Разберем простой пример программы, приведенной на листинге 2. Основными синтаксическими конструкциями в коде являются:

с.1 объявление глобальной переменной для этого проекта. Переменную можно использовать в любой функции кода, так как она имеет глобальную область видимости.

с.2 объявление константной , глобальной переменной целочисленного типа. Ее значение не может быть изменено в ходе работы программы.

с.5 присвоение нового значения переменной count.

с.6 установка режима работы вывода под номером, которых хранится в переменной pin, в режим выхода.

с.9 условная конструкция, условием которой является результат вычисления логического выражения чтения состояния вывода номер, которого хранится в переменной pin, с последующей инверсией.

с.11 инструкция внутри тела блока if, инкрементирующая переменную count на единицу. Постфиксная запись инкремента после имени переменной, позволяет использовать значение переменной в выражении , и после вычисления выражения произвести инкремент.

с.14 задержка выполнения пользовательских функций на 10 мс.

с.15 вызов функции TogglePin с передачей аргумента. Вызывается функция описанная сигнатурой: void Func(int), где Func - имя функции , int , единственный параметр целочисленного типа.

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

Для установки выводов для работы в режиме входа, можно не использовать принудительную установку функцией pinMode т.к. после перезагрузки все вывод устанавливаются по умолчанию в режим входа, но для наглядности и явной видимости, для программиста, стоит это делать. Для функции digitalWrite можно использовать различную запись логического уровня: LOW / HIGH, true / false, 0/1 и т.д. В языке С++ все значения, кроме нуля и null это ИСТИНА, поэтому возов:

digitalWrite(3 , -100.12) установит на третьем выводе высокий уровень напряжения (3.3В для платы Node MCU).

Если к выводу №3 подключен светодиод, то программа, приведенная на листинге 1, позволяет зажигать его и гасить. Задержка определяет длительность свечения светодиода.

После отладки приведенного кода внесите следующие изменения, выполнив Задание 1.

Задание 1.

  1. измените длительность свечения светодиода;

  2. измените номер вывода подключения светодиода, для вспышки;

  3. используйте несколько светодиодов для попеременных вспышек;

  4. используйте несколько светодиодов для последовательных вспышек;

  1. ПОСТРОЕНИЕ АЛГОРИТМА С ИСПОЛЬЗОВАНИЕМ ЦИКЛА

В данной части работы осуществляется построение простого алгоритма с использованием цикла. Программа модифицирована с применением переменных, для обозначения используемых выводов. Цикл for в С++ имеет 3 необязательных аргумента и при отсутствии всех запись вырождается в вид: for( ; ; ) { }.

Три аргумента цикла имеют назначение и особенности:

  1. Итератор переменная, по которой будет производиться, инкрементация. Это счетчик, который будет отвечать за отслеживание количества проходов цикла. Переменную в языке С++ можно не объявлять непосредственнов цикле, а использовать внешнюю. Счетчик не обязательно должен быть целочисленным.

Пример: for(float t = 0.0; t< 3.4; t + 1.74){}.

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

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

Пример: for ( int i = 2; i<10 ; i++) { }.

Пример использования цикла forприведен на Листинге 2.

intpin_led = 3;

void setup() {

pinMode(pin_led, OUTPUT);

}

void loop() {

int decay = 200;

for(inti = 10; i> 0; i--)

{

digitalWrite(pin_led, true);

delay(decay);

digitalWrite(pin_led, false);

delay(decay);

}

}

Листинг 2. Использование цикла for

После отладки приведенного кода внесите изменения, выполнив Задание 1.

  1. ИСПОЛЬЗОВАНИЕ УСЛОВИЙ

Выполните загрузку кода примера (листинг 3) в лабораторный макет, для дальнейшей модификации и работы с ним. Обратите внимание, что теперь нумерация используемых выводов замещена переопределениями директивой препроцессора #define. Переопределение содержит два аргумента: название и замещающий текст, разделенные пробельными символами. Важно отметить, что не нужно ставить точку с запятой после завершения переопределения, так как символ точки с запятой войдет в текст переопределения, что вызовет ошибку компиляции, например:

#define PIN 4;

pinMode(PIN, OUTPUT);

Внутри вызова функции pinMode произойдет ошибка, так как вызов не будет обладать вторым аргументом и закрывающей скобкой: pinMode (4 ,OUTPUT);

#define PIN_LED1 3

#define PIN_BUT1 4

constint decay = 200;

void setup() {

pin_setup();

}

void loop() {

button_check(PIN_BUT1, decay);

}

void pin_setup() {

pinMode(pin_led, OUTPUT);

pinMode(PIN_BUT1, INPUT_PULLUP);

}

void button_check(intpin_but, intblinkDecay)

{

if( !digitalRead(pin_but) )

{

for(inti = 0; i< 10; i++)

{

digitalWrite(PIN_LED1, !digitalRead(PIN_LED1));

delay(blinkDecay);

}

}

}

Листинг 3. Использование условий

Приведенные функции среды Arduino, используемые в примере, позволяют реализовать более сложное поведение алгоритма. digitalRead(n) функция получения булевого значения, прочитанного с входамикроконтроллера, и соответствующего логическому напряжению, установленному на указанном (n) выводе. Причем, чтение состояния возможно при работе вывода как на вход, так и на выход. В функции setup используется вызов самоопределенной функции pin_setup(). Эта функция не принимает обязательных аргументов, в своем теле содержит функционал по настройке выводов, для дальнейшей работы, поэтому название функции выбрано, чтобы отражать назначение функции. После выполнения тела pin_setup(), управление возвращается функции setup(), но так далее нет инструкций , то она завершает свою работу и управление передается функции loop().

Для управления миганием светодиода используется функция button_check(int, int). Она имеет два обязательных аргумента: номер вывода, на который подключен светодиод, и значение задержки междумоментами переключения состояния светодиода.

После выполнения приведенного кода внесите изменения, выполнив Задание 2.

Задание 2.

  1. Выполните п.1-4 из Задания 1;

  2. напишите еще одну пользовательскую функцию, для проверки положения второго тумблера и дублирования его состояния на светодиод (вкл / выкл);

  3. определите все выводы и используемые константы, через переопределения.

Контрольные вопросы

  1. Какая функция позволяет установить режим работы вывода?

  2. Какая функция позволяет установить логический уровень на выводе?

  3. Какая функция позволяет прочитать логическое состояние вывода?

  4. Какие аргументы у цикла for, за что они отвечают?

  5. Для чего может служить директива препроцессора #define?

  6. В какой цикл вырождается for при отсутствии 2-го обязательного аргумента условия?

  7. В какой цикл вырождается for при отсутствии 3-го обязательного аргумента выражения-модификатора?

  8. Что обозначает оператор «!»?(В тексте отсутствует пояснение по этому оператору)

  9. Что такое переопределение функции?(Про переопределение функции разве есть в тексте?)

  10. Что такое локальная область видимости?

  11. Что такое глобальная область видимости?

  12. Для чего используется переопределение в языке С++ ?(В тексте нет пояснений для чего!)

  13. Какие шаги нужно выполнить, для объявления новой функции?

  14. Как называется оператор «++»?В тексте нет пояснений)

  15. Какая переменная называется «локальной»?

  16. Напишите эквивалентные формы записи выражения: i = i +1;

  17. Что обозначает запись: constintnumber = 6;?

  18. Приведите пример кода переключения состояния вывода.

  19. Приведите пример кода настройки нескольких выводов на вход.

  20. Приведите пример кода проверки состояния вывода.

Список литературы:

  1. Советов Б.Я., Яковлев С.А. Моделирование систем. Практикум. М.: Высшая школа, 2009. (Гриф УМО по университетскому политехническому образованию в качестве учебника для студентов вузов, обучающихся по направлениям «Информатика и вычислителельная техника» и «Информационные системы»), тираж 3000, объем 21,07 п.л.).

  2. Представление и обработка структурированных данных: Практикум по программированию / Ивановский С.А., Калмычков В.А., Лисс А.А., Самойленко В.П.; Санкт-Петербургский государственный электротехнический университет им. В.И. Ульянова (Ленина) "ЛЭТИ". - СПб. : Изд-во СПбГЭТУ "ЛЭТИ", 2002 - 96 с

  3. Калмычков В.А. Использование структурированных данных при программировании на языке С++: Учеб. пособие. СПб.: Изд-во СПбГЭТУ “ЛЭТИ”, 2011 - 48 с.

  4. Справочник функций языка Lua для платформы Arduino / Интернет ресурс (URL: https://all-arduino.ru/programmirovanie-arduino/, дата обращения 20.09.2023)