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

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

 

 

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

 

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

 

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

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

*