ESP8266 Урок 7. UART. Передача данных



Продолжаем учиться писать код для микроконтроллера ESP8266.

И сегодня мы попробуем передать какие-нибудь данные с нашего модуля по шине UART на ПК.

С данным интерфейсом мы уже прекрасно знакомы из курсов занятий по программированию других МК, знаем протокол передачи, поэтому нам будет несложно, вооружившись знанием функционала SDK, настроить данный модуль UART и передать с него данные. Причём в технической документации на ESP8266 назван он именно UART, а не USART, как мы привыкли, из чего мы можем понять, что данная периферия та же, что и у других контроллеров, только здесь нет синхронизации.

Также в технической документации мы видим, что у контроллера два модуля UART, один из которых поддерживает ещё и аппаратный контроль, так как у него есть контакты RTS и CTS, а другой только приём и передачу. Максимальная скорость передачи данных заявлена производителем аж целых 4,5 Mbps.

Мы воспользуемся в нашем занятии самым первым полноправным модулем UART0, хотя аппаратный контроль мы использовать не будем.

Тем более выбор для занятия именно UART0 ещё обусловлен и тем, что к данному модулю уже подключена микросхема-переходник на нашей плате NodeMCU, конвертирующая поток данных между интерфейсами USB и UART. Если у кого обычный модуль ESP-01, то нужно будет подключать к ножкам GPIO1 и GPIO3 соответствующий переходник.

Также через этот же интерфейс UART0 мы считываем и записываем прошивку в наш модуль. В этом ничего страшного нет и никаких коллизий на этот счёт у нас не будет, так как в момент прошивания ПО в нашем МК не запущено, а в момент работы ПО мы ничего не прошиваем.

Также к нашей плате к ножкам RX и TX, выведенных ещё и наружу, мы подключим логический анализатор для того, чтобы посмотреть, как у нас будет происходить передача данных по UART

 

 

Думаю, что с функционалом SDK мы лучше будем знакомиться по мере настройки и использования нашего UART, так будет интереснее.

Проект мы сделаем из проекта прошлого урока BUTTON01 и назовём его UART_TX.

В качестве вступления давайте немного ещё улучшим наш файл сценария сборки Makefile.

Мы нашу основную цель all разобьём на несколько и добавим зависимости, благодаря которым у нас не будут формироваться новые файлы, если те, от которых они зависят, не были изменены.

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

 

 

Теперь, если эти два файла не изменятся, у нас не будет формироваться объектный файл

Далее добавим следующую цель — формирование архивного файла, включающего в себя все объектные файлы

 

 

Данная цель будет зависеть от результата предыдущей.

Добавим ещё одну цель — формирование исполняемого файла формата ELF

 

 

 

Остальное оставим в цели all, только для начала добавим теперь для неё зависимость от самой нашей последней цели

 

all: build/app.out

 

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

 

@echo «CC src/main.o»

@$(CC) -Iinc -I$(SDK_INC) -I$(SDK_INC)/json $(CC_FLAGS) src/main.c -o src/main.o

@echo «AR build/app_app.a»

@$(AR) cru build/app_app.a src/main.o

@echo «LD build/app.out»

@$(LD) -L$(SDK)/lib -T$(SDK)/ld/eagle.app.v6.ld $(LD_FLAGS) build/app_app.a \

-Wl,—end-group -o build/app.out

 

Теперь у нас будет всё нормально и если файлы зависимостей не модифицировались, то цели, зависящие от них, выполняться не будут.

Теперь в файле main.c для начала удалим макрос для кнопки, так как в данном проекте мы её использовать не будем

 

#define BUTTON 4

 

Также удалим вот эти строки настройки ножки кнопки

 

PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO4_U, FUNC_GPIO4);

PIN_PULLUP_EN(PERIPHS_IO_MUX_GPIO4_U);

 

И вот эту

 

gpio_output_set(0, 0, 0, (1 << BUTTON));

 

В бесконечном цикле удалим условие, оставив его тело

 

if(!((gpio_input_get()>>BUTTON) & BIT0))

{

   gpio_output_set(0, (1 << LED), 0, 0);

}

 

Мы практически вернули код нашей мигалки из 5 урока, только я не стал делать проект для данного урока из проекта того урока, потому что мы ещё меняли процесс сборки.

Теперь по настройке UART.

Для начала подключим заголовочный файл библиотеки с прототипами функций для работы с UART

 

 

Только ввиду того, что каталог с такими библиотеками у нас не подключен, проект у нас не соберётся. Поэтому для начала добавим её в настройках проекта в соответствующем месте

 

 

 

Также данный путь добавим в Makefile в виде переменной

 

 

И добавим данную переменную в соответствующую команду

 

@$(CC) -Iinc -I$(SDK_INC) -I$(SDK_INC)/json -I$(SDK_DRIVER_INC) $(CC_FLAGS) src/main.c -o src/main.o

 

Теперь проект соберётся.

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

Почему так будет происходить и как с этим бороться, мы чуть позже узнаем.

А пока добавим переменную для счётчика в app_main()

 

 

А вот теперь вызовем функцию инициализации из подключенной библиотеки, в двух параметрах которой передадим желаемую скорость работы обоих наших модулей UART

 

 

И мы получим вот такую ошибку при линковке

 

 

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

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

Так как нам никаких особенных настроек пока не требуется, то подключим в Makefile соответствующую статическую библиотеку

 

@$(LD) -L$(SDK)/lib -T$(SDK)/ld/eagle.app.v6.ld $(LD_FLAGS) build/app_app.a $(SDK)/lib/libdriver.a \

 

Вот теперь всё соберётся.

С отправкой строк вообще нет проблем, есть специальная функция os_printf из библиотеки osapi, которую мы подключили на прошлом уроке. Данная функция умеет по формату передавать строки в UART0.

В бесконечном цикле в обоих задержках прибавим интервал

 

ets_delay_us(1000000);

 

Давайте что-нибудь передадим, например номер итерации нашего бесконечного цикла

 

 

И чтобы наш итератор наращивался, добавим его инкрементирование и ограничив максимальное число, при котором будет итератор сбрасываться

 

 

Настроим терминальную программу на соответствующий порт, пока не соединяемся, соберём код, прошьём контроллер, соединимся с портом в терминальной программе и увидим, что все наши строки благополучно приходят в окно терминала

 

 

Отлично! Всё передаётся.

Ну, раз уж так у нас быстро всё получилось с передачей данных, давайте передадим ещё что-нибудь полезное.

В технической документации по SDK существует ряд таких информационных полезных функций в разделе 3.3. System APIs.

Вызовем некоторые из них

 

 

Данные функции имеют говорящие имена, которые подсказывают нам, какую информацию возвращает каждая функция, также описание есть и в документации. Например мы выведем в терминал версию SDK, системное время, время с момента запуска МК, информацию о свободном месте в памяти и т.д.

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

 

 

Также мы помним, что у нас подключен логический анализатор, давайте посмотрим, что происходит на ножке TX нашего UART0 при передаче данных

 

 

Мы видим, что всё передаётся бесперебойно и отлично распознаётся программой логического анализа.

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

Всем спасибо за внимание!

 

 

Предыдущий урок Программирование МК ESP8266 Следующий урок

 

Исходный код

 

 

Модуль ESP NodeMCU можно купить здесь: Модуль ESP NodeMCU

Различные модули ЕSP8266 можно приобрести здесь Модули ЕSP8266

Переходник USB to TTL можно приобрести здесь ftdi ft232rl

Многофункциональный переходник JTAG UART FIFO SPI I2C можно приобрести здесь CJMCU FT232H USB к JTAG UART FIFO SPI I2C

Логический анализатор 16 каналов можно приобрести здесь

 

 

Смотреть ВИДЕОУРОК в RuTube (нажмите на картинку)

ESP8266 UART. Передача данных

 

Смотреть ВИДЕОУРОК в YouTube (нажмите на картинку)

ESP8266 UART. Передача данных

 

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

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

*