На плате Maixduino есть 3 последовательных порта (UART): "/dev/uart1"
, "/dev/uart2"
и "/dev/uart3"
. Первый порт ("/dev/uart1"
) используется FreeRTOS как порт для отладки и прошивки. По этому не рекомендуется использовать, а два других порта можно использовать для обмена данными с внешними устройствами.
В этом уроке настроим последовательный порт (UART), напишем пример программы и будем передавать данные между Maixduino и компьютером.
Настройка UART порта
Перед использованием последовательного порта его необходимо настроить. Сначала в файле project_cfg.h
мы устанавливаем контакты (пины) Rx и Tx. Более подробно о настройке выходов / входов вы можете прочитать в первом уроке: Урок 1. Кнопка, светодиод. Функции управления вводом/выводом. Первая программа.
#ifndef PROJECT_CFG_H #define PROJECT_CFG_H #include <pin_cfg.h> #define UART1_RX_PIN (13) #define UART1_TX_PIN (14) const fpioa_cfg_t g_fpioa_cfg = { /* Версия */ .version = PIN_CFG_VERSION, /* Число функций */ .functions_count = 2, /* Офисание функций */ .functions = { /* */ {UART1_RX_PIN, FUNC_UART2_RX}, {UART1_TX_PIN, FUNC_UART2_TX}, }, }; #endif
Rx и Tx устанавлны на контакты 13 и 14 соответственно.
После этого необходимо открыть устройство uart2
с помощью функции io_open
.
/* Открываем UART2 устройство */ gpio = io_open("/dev/uart2");
И наконец настраиваем скорость COM порта, биты данных, количество стоп-бит и бит четности.
uart_config(uart2, 115200, 8, UART_STOP_1, UART_PARITY_NONE);
Также задаём тайм-аут для чтения:
uart_set_read_timeout(uart2, UINT32_MAX);
Примеры программ с UART
Напоследок приведу пример программы. В этой программе мы настроим выходной контакт, на этот контакт будет установлен светодиод, который будет мигать с определенным интервалом. Порт UART2 также будет настроен для обмена данными между Maixduino и компьютером. Миганть светодиодом будет задача static void blinkLedTask(void *pvParameters)
, принимать и передать данных по UART — static void uartTask(void *pvParameters)
.
Всё это дело выглядит следующим образом:
Чтобы лучше понять, как работает программа, почти к каждой строчке кода были добавлены комментарии.
Схема подключения
Светодиод подключается на 13-й контакт Maixduino/Arduino через резистор, ограничивающий ток. Преобразователь USB-UART подключается к контактам 8 и 9, Rx и Tx соответственно. В качестве конвертера можно использовать: PL2303, CH340, CP2102 или любой другой доступный.
Файл project_cfg.h
#ifndef PROJECT_CFG_H #define PROJECT_CFG_H #include <pin_cfg.h> /** * Номер внутреннего пина */ #define LED_IO (0) /** * Номер физического пина */ #define LED_PIN (3) #define UART1_RX_PIN (13) #define UART1_TX_PIN (14) const fpioa_cfg_t g_fpioa_cfg = { /* Версия */ .version = PIN_CFG_VERSION, /* Число функций */ .functions_count = 3, /* Офисание функций */ .functions = { /* */ {LED_PIN, static_cast<fpioa_function_t>(FUNC_GPIOHS0 + LED_IO)}, {UART1_RX_PIN, FUNC_UART2_RX}, {UART1_TX_PIN, FUNC_UART2_TX}, }, }; #endif
Файл main.cpp
#include "project_cfg.h" #include <FreeRTOS.h> #include <devices.h> #include <string.h> #include <syslog.h> #include <task.h> /** * Указатель на устройство UART 2 */ static handle_t uart2; /** * Указатель на устройство GPIO */ static handle_t gpio; /** * Текущее состояние светодиода */ static gpio_pin_value_t ledState; /** * Прототип задачи включения/выключения светодиода * * @param pvParameters Функции задач принимают параметр, имеющий тип указателя на void (т. е. void*). * Значение, указанное в pvParameters, будет передано в задачу. */ static void blinkLedTask(void *pvParameters); static void uartTask(void *pvParameters); int main() { BaseType_t retCode; const char helloMessage[] = "hello uart!\r\n"; /* Открываем GPIO0 устройство */ gpio = io_open("/dev/gpio0"); /* Перехват ошибок в процессе разработки */ configASSERT(gpio); /* Открываем uart2 устройство */ uart2 = io_open("/dev/uart2"); /* Перехват ошибок в процессе разработки */ configASSERT(uart2); /* Устанавливаем режим работы LED_IO пина на выход. */ gpio_set_drive_mode(gpio, LED_IO, GPIO_DM_OUTPUT); /* Задаём начальное состояние светодиода (выключаем) */ ledState = GPIO_PV_LOW; /* Пишем состояние в пин */ gpio_set_pin_value(gpio, LED_IO, ledState); uart_config(uart2, 115200, 8, UART_STOP_1, UART_PARITY_NONE); uart_set_read_timeout(uart2, UINT32_MAX); /* Создаём задачу с мигающим светодиодом */ retCode = xTaskCreateAtProcessor(0, blinkLedTask, "Blink Led task", 512, nullptr, 3, nullptr); /* Проверяем, если задача была успешно создана */ if (retCode == pdPASS) { /* В случае успеха выводим информационное сообщение */ LOGI("MFRB", "Blink Led task is running"); } else { /* В случае неудачи выводим предупреждающее сообщение */ LOGW("MFRB", "Blink Led task start problems"); } /* Создаём задачу с мигающим светодиодом */ retCode = xTaskCreateAtProcessor(1, uartTask, "Uart Task task", 1024, nullptr, 3, nullptr); /* Проверяем, если задача была успешно создана */ if (retCode == pdPASS) { /* В случае успеха выводим информационное сообщение */ LOGI("MFRB", "Uart Task task is running"); } else { /* В случае неудачи выводим предупреждающее сообщение */ LOGW("MFRB", "Uart Task task start problems"); } io_write(uart2, (uint8_t *)helloMessage, strlen(helloMessage)); for (;;) { } return 0; } static void blinkLedTask(void *pvParameters) { /* Время повторения */ unsigned int timeInMs; for (;;) { /* Меняем состояние в 1/0 */ if (GPIO_PV_HIGH == ledState) { ledState = GPIO_PV_LOW; timeInMs = 900; } else { ledState = GPIO_PV_HIGH; timeInMs = 100; } /* Пишем новое состояние в пин */ gpio_set_pin_value(gpio, LED_IO, ledState); /* Помещаем задачу в состояние Blocked на фиксированное количество тиков прерываний. Находясь в состоянии Blocked, задача не использует процессорное время, поэтому процессор загружен только полезной работой. С помощью макроса pdMS_TO_TICKS мы конвертируем миллисекунды в тики */ vTaskDelay(pdMS_TO_TICKS(timeInMs)); } } static void uartTask(void *pvParameters) { /* Полученный символ */ uint8_t receivedChar = 0; for (;;) { /* */ if (io_read(uart2, &receivedChar, 1) < 0) { /* Предупреждение о тайм-ауте */ LOGW("MFRB", "time out"); } else { /* Отправка символа обратно */ io_write(uart2, &receivedChar, 1); } } }
Результат
После компиляции программы и прошивки контроллера подключаемся к компьютеру через конвертер USB-UART. Открываем Arduino IDE, выбираем порт, который соответствует преобразователю, и открываем монитор порта.
Если нажать кнопку «RESET«, в консоли должно появиться сообщение «hello uart!«.
После появления сообщения мы можем отправить несколько символов (к примеру 1235467890), и мы получим эти символы обратно.
Материалы
Kendryte · GitHub
Maixduino-4.30(schematic)
Maixduino — одноплатный компьютер с ускорителем AI, RISC-V AI, форм-фактор Arduino и беспроводной модуль ESP32
вызов нарколога на дом частная скорая помощь вызов нарколога на дом частная скорая помощь .
Вывод из запоя в Алматы Вывод из запоя в Алматы .
Профессиональный сервисный центр по ремонту компьютероной техники в Москве.
Мы предлагаем: ремонт блоков компьютера
Наши мастера оперативно устранят неисправности вашего устройства в сервисе или с выездом на дом!