Что такое программный UART. Как реализовать программный UART для микроконтроллера. Какие преимущества дает использование программного UART. Какие ограничения существуют при реализации программного UART.
Что такое программный UART и зачем он нужен
Программный UART (Universal Asynchronous Receiver-Transmitter) — это программная реализация последовательного интерфейса связи, которая эмулирует работу аппаратного UART с помощью программного кода. Основные причины использования программного UART:
- Недостаточное количество или отсутствие аппаратных UART в микроконтроллере
- Необходимость реализации нестандартных скоростей передачи данных
- Экономия аппаратных ресурсов микроконтроллера
- Гибкость в выборе пинов ввода-вывода для реализации UART
Программный UART позволяет организовать асинхронный последовательный обмен данными практически на любых пинах микроконтроллера, что значительно расширяет возможности разработки.
Принцип работы программного UART
Программный UART эмулирует работу аппаратного UART, реализуя следующие основные функции:
- Формирование кадра передачи данных (старт-бит, биты данных, бит четности, стоп-биты)
- Генерация тактовых импульсов для передачи и приема на заданной скорости
- Побитовая передача и прием данных с помощью программных циклов
- Обработка прерываний таймера для точной синхронизации
- Буферизация принятых и передаваемых данных
Ключевое отличие от аппаратного UART заключается в том, что все операции выполняются программно с использованием ресурсов процессора, а не специализированных аппаратных модулей.
Реализация программного UART на микроконтроллере
Основные шаги для реализации программного UART на микроконтроллере:
- Настройка пинов ввода-вывода для RX и TX линий
- Инициализация таймера для генерации прерываний с частотой, кратной требуемой скорости передачи
- Реализация функций передачи и приема битов данных
- Создание кольцевых буферов для хранения принятых и передаваемых данных
- Реализация функций высокого уровня для отправки и приема байтов данных
Важно обеспечить точную синхронизацию и минимизировать влияние прерываний на работу основной программы. Для этого часто используются техники оптимизации кода и тщательная настройка приоритетов прерываний.
Преимущества использования программного UART
Реализация программного UART дает ряд преимуществ разработчикам встраиваемых систем:
- Возможность создания дополнительных UART-интерфейсов без изменения аппаратной части
- Гибкость в выборе пинов для RX и TX линий
- Реализация нестандартных скоростей передачи данных
- Экономия аппаратных ресурсов микроконтроллера
- Возможность динамического изменения параметров UART во время работы
Это позволяет оптимизировать использование ресурсов микроконтроллера и повысить гибкость разрабатываемых систем.
Ограничения и недостатки программного UART
При использовании программного UART следует учитывать некоторые ограничения:
- Повышенная нагрузка на процессор, особенно на высоких скоростях передачи
- Меньшая точность тайминга по сравнению с аппаратным UART
- Ограничение максимальной скорости передачи данных
- Возможность потери данных при высокой загрузке процессора
- Сложность реализации некоторых расширенных функций (например, аппаратного управления потоком)
Для минимизации этих недостатков требуется тщательная оптимизация кода и правильный выбор параметров передачи данных.
Оптимизация программного UART
Для повышения производительности и надежности программного UART можно применить следующие методы оптимизации:
- Использование ассемблерных вставок для критичных по времени участков кода
- Применение техники разворачивания циклов (loop unrolling)
- Оптимизация обработки прерываний и минимизация их длительности
- Использование DMA для буферизации данных
- Тщательный выбор размеров буферов и оптимизация работы с ними
Эти методы позволяют значительно повысить производительность и надежность программного UART, приближая его характеристики к аппаратной реализации.
Применение программного UART в проектах
Программный UART находит широкое применение в различных проектах на базе микроконтроллеров:
- Отладка и мониторинг встраиваемых систем
- Связь с внешними устройствами (например, GPS-модулями, датчиками)
- Реализация нестандартных протоколов связи
- Создание виртуальных последовательных портов
- Эмуляция устройств с последовательным интерфейсом
Гибкость программного UART позволяет адаптировать его под различные требования проектов и эффективно использовать ресурсы микроконтроллера.
Заключение
Программный UART является мощным инструментом в арсенале разработчика встраиваемых систем. Несмотря на некоторые ограничения, его гибкость и возможность реализации на широком спектре микроконтроллеров делают его незаменимым в ситуациях, когда аппаратных ресурсов недостаточно или требуется нестандартная функциональность. Правильная реализация и оптимизация программного UART позволяют создавать эффективные и надежные системы связи в проектах различной сложности.
Программный UART для любого микроконтроллера. Ч1
Иногда возникает ситуация, когда аппаратных ресурсов микроконтроллера не хватает или требуемый ресурс в его составе отсутствует. Решить эту проблему можно двумя способами – заменить используемый микроконтроллер на другой или реализовать требуемый ресурс программно. Оба способа имеют свои достоинства и недостатки, однако второй вариант часто более предпочтительный, а иногда и единственно возможный. Например, как в случае с 1-Wire интерфейсом, который не поддерживается аппаратно ни в одном 8-ми разрядном микроконтроллере AVR.
В этой статье рассмотрена реализация программного UART`а, которую можно модифицировать под любой микроконтроллер, программируемый на Си. Во второй части статьи будет рассмотрена реализация программного UART`а модифицированного под микроконтроллер AVR. Материал написан на основе IAR`овского апноута, найденного на просторах интернета.
Для использования кода программного UART`а, необходимо выполнение следующих требований:
1. Наличие Си компилятора под используемый микроконтроллер
2. Наличие у микроконтроллера таймерного прерывания.
3. Наличие у микроконтроллера двух выводов, состояние которых можно программно читать и изменять.
В данном коде реализованы следующие функции.
1. void flush_input_buffer( void )
Очистка входного (приемного) буфера.
2. char kbhit( void )
Тестирование входного буфера на наличие данных.
3. char getchar( void )
Чтение символа из входного буфера.
Принимаемые данные сохраняются в кольцевом буфере, емкость которого задается с помощью макроопределения.
Если на момент вызова данной функции входной буфер пуст, функция ожидает поступление данных. При этом в цикле выполняется пользовательская функция idle(). Про нее написано ниже.
4. void turn_rx_on( void )
Разрешает прием данных по UART`у. По умолчанию прием данных разрешен.
5. void turn_rx_off( void )
Запрещает прием данных по UART`у.
Прием и передача данных выполняется в обработчике прерывания таймера. Запрещение приема данных уменьшает время выполнения обработчика.
6. void putchar( char )
Запись символа в последовательный порт
7. void init_uart( void )
Инициализация программного UART`a. Устанавливает внутренние флаги, настраивает выводы микроконтроллера и таймер.
Данная программная реализация UART`а основана на использовании прерывания таймера. Разрядность таймера и режим работы значения не имеют, главное чтобы частота его прерываний могла быть установлена в три раза выше требуемой скорости обмена.
Например, требуется скорость 9600 бит в секунду. Тогда прерывания таймера должны происходить с частотой 9600*3 = 28800 Гц. Или в пересчете на временной интервал – каждые 34,72 микросекунды.
Это накладывает скоростные ограничения на возможности применения программного UART`a, особенно в микроконтроллерах с низкой тактовой частотой.
Если установить слишком высокую скорость обмена, код обработчика прерывания таймера не будет успевать выполняться между вызовами прерываний, что приведет к ошибкам приема/передачи, а то и к полной потере связи.
Также высокая частота прерываний таймера будет негативно влиять на производительность остальной части программы. (Для аналогии можно привести ситуацию, когда вы пытаетесь выполнять свою работу, а вас постоянно отвлекают на посторонние дела.)
Код программного UART`a из IAR`овского апноута записан в сишном файле. Подключить его к проекту можно двумя путями:
– скопировать этот код в один из сишных файлов своего проекта
– написать к сишному файлу заголовочный и подключить к проекту полноценный модуль
Второй путь более грамотный, поэтому программный UART во второй части статьи я подключаю к проекту именно так.
Однако это еще не все.
Для переносимости кода в нем не реализовано несколько платформенно-зависимых функций, которые вам потребуется написать. Функции перечислены в списке ниже.
В принципе ничего сложного в этом нет.
1. void get_rx_pin_status( void )
Возвращает состояние приемного вывода (receive pin).
2. void set_tx_pin_high( void )
Устанавливает на передающем выводе (transmit pin) логическую единицу.
3. void set_tx_pin_low( void )
Устанавливает на передающем выводе логический ноль.
4. void idle( void )
Фоновая пользовательская функция. Выполняется, когда ожидается прием данный.
5. void timer_set( int BAUD_RATE )
Устанавливает частоту прерываний таймера. Частота прерываний должна быть в 3 раза выше требуемой скорости обмена!
Функции передается значение требуемой скорости обмена, а она должна устанавливать соответствующую частоту таймерных прерываний.
6. void set_timer_interrupt( timer_isr )
Разрешает прерывания таймера.
Для экономии памяти и увеличения производительности кода некоторые из этих функций можно заменить макросами. Например, функции 1, 2, 3 и 6.
Функцию 4 можно оставить пустой.
И последнее что нужно сделать, это поместить код функции void timer_isr(void) в прерывание таймера. Сделать это можно опять-таки двумя способами:
— поместить вызов функции timer_isr() в код обработчика прерывания
— сделать из самой функции timer_isr() обработчик прерывания
Второй вариант более грамотный, поскольку требует меньших накладных расходов – оперативной памяти и процессорного времени. Впрочем, ты и так должен знать, к чему приводит вызов функций из прерываний.
Программный UART вторая часть…
software-uart.rar
Урок 14. Программный UART в BASCOM-AVR « схемопедия
В некоторых AVR микроконтроллерах отсутствует аппаратный UART интерфейс связи или по некоторым причинам он не может быть использован. Как же тогда поступить? Можно конечно использовать другой микроконтроллер, но проще и дешевле реализовать программный UART. Его преимущество в том, что программный UART можно реализовать практически на любом AVR микроконтроллере и на любых портах вводавывода.
Об этом и пойдёт речь в этом уроке.Программный UART по работе практически ни чем не отличается от аппаратного за исключением того, что для программного нужно чуть больше Flash и RAM памяти чем для аппаратного.
Программная реализация
Чтобы в BASCOM-AVR реализовать программный UART нужно, сначала сконфигурировать порты вводавывода на передачу TXD:
Open ” порт : скорость , биты , чётность , стоп биты ” For Output As #1
И на приём RXD:
Open ” порт : скорость , биты , чётность , стоп биты
Порт необходимо указывать так: com ножка вводавывода, например: comb.3 порт на ножку вводавывода PB.3 . Скорость, биты, четность и стоп биты указывать как обычно.
Пример команды конфигурации на передачу TXD:
Open “comb.3:9600,8,n,1” For Output As #1
Пример команды конфигурации на приём RXD:
Open “comb.4:9600,8,n,1” For Input As #2
После конфигурации с программным UART можно работать с помощью команд на передачу: Print #1 , данные и на приём: Input #2 , переменная
Стоит помнить что частота, выставленная в BASCOM-AVR командой $crystal должна совпадать с реальной частотой микроконтроллера выставленной фьюз-битами.
Практическая реализация
Теперь попробуем на практике реализовать программный UART. За основу возьмём микроконтроллер без аппаратного UART – ATtiny13, светодиод, кнопку и пару резисторов. Соберём простую схему:
Программа для микроконтроллера будет работать по следующему алгоритму: сначала вывод сообщений потом ожидание команд (LED=1 – включить светодиод, LED=0 – выключить светодиод). В BASCOM-AVR программа выглядит так:
$regfile = “attiny13.dat” $crystal = 9600000 $hwstack = 16 $swstack = 16 $framesize = 16 Open “comb.3:9600,8,n,1” For Output As #1 Open “comb.4:9600,8,n,1” For Input As #2 Dim Cmd As String * 8 Config Portb.2 = Output Print #1 , “Program UART for AVR microcontroller Attiny13” Print #1 , “——” Print #1 , “Developer: Yakovlev Alexander” Print #1 , “E-mail: [email protected]” Print #1 , “——” Print #1 , “Hello http://cxem.net !!!” Print #1 , “——” Do Print #1 , “Command:” Input #2 , Cmd If Cmd = “LED=1” Then Portb.2 = 1 Print #1 , “DONE!” End If If Cmd = “LED=0” Then Portb.2 = 0 Print #1 , “DONE!” End If Loop End
Откомпилируйте программу и прошейте ею микроконтроллер. Фьюз-биты необходимо установить на тактирование микроконтроллера от внутреннего тактового генератора на 9.6 МГц без делителя на 8. Пример установки фьюз-битов в программе SinaProg:
Для связи с микроконтроллером по UART можно использовать USB-UART переходник (я так и поступил) и программу Terminal Emulator в BASCOM-AVR. После подачи питания на микроконтроллер и запуска программы нажмите кнопку, указанную на схеме для сброса микроконтроллера.
Я собирал схему на макетной плате, вот что получилось:
Автор: Яковлев Александр Вячеславович
Прикрепленные файлы:
- bascom14.rar (14 Кб)
Программное обеспечение UART
Программное обеспечение UART. Подробнее…
Программно реализованный UART.
Этот модуль обеспечивает программно реализованный универсальный асинхронный приемник-передатчик. Он предназначен для использования в ситуации, когда аппаратный UART недоступен. Сигнатуры функций аналогичны функциям, объявленным в uart.h
В настоящее время одновременная отправка и получение невозможны, поэтому петлевая операция невозможна.
файл | soft_uart.h |
Программное определение дескриптора порта UART. | |
файл | soft_uart_params.h |
Struct | SOFT_UART_CONF_T |
Программное обеспечение UART. Подробнее… | |
#define | SOFT_UART_FLAG_INVERT_TX 0x1 | |
инвертировать уровень сигнала TX | ||
soft_uart_flag_invert_rx 0x2 | ||
Инвертировать уровень сигнала RX | ||
0013 | |
typedef unsigned | soft_uart_t |
Программное определение типа UART. | |
int | soft_uart_init (soft_uart_t uart, uint32_t baudrate, uart_rx_cb_t rx_cb, void *arg) |
Initialize a given UART device. Подробнее… | |
int | soft_uart_mode (soft_uart_t uart, uart_data_bits_t data_bits, uart_parity_t parity, uart_ttop_bits_ |
Установка битов четности, данных и стоповых битов для данного устройства UART. Подробнее … | |
void | soft_uart_write (soft_uart_t uart, const uint8_t *data, size_t len) |
void | soft_uart_poweron (soft_uart_t uart) |
Включите данное устройство UART. Подробнее… | |
void | soft_uart_poweroff (soft_uart_t uart) |
Выключение данного устройства. Подробнее… | |
◆ soft_uart_init()
int soft_uart_init | ( | soft_uart_t | порт , |
uint32_t | скорость передачи , | ||
uart_rx_cb_t | rx_cb , | ||
пустота * | аргумент | ||
) |
Инициализировать данное устройство UART.
Устройство UART будет инициализировано со следующей конфигурацией:
- 8 бит данных
- нет четности
- 1 стоповый бит
- скорость передачи данных
Если параметр обратного вызова не задан (rx_cb := NULL), UART будет инициализирован только в режиме TX.
- Параметры
[in] uart Устройство UART для инициализации [in] скорость передачи требуемая скорость передачи символов в бодах [in] rx_cb обратный вызов приема, выполняется в контексте прерывания один раз для каждого полученного байта (буфер RXULL заполнен) только для режима TX [in] arg дополнительный контекст, передаваемый функциям обратного вызова
- Возвращает
- UART_OK в случае успеха
- UART_NODEV на недопустимом устройстве UART
- UART_NOBAUD на неприменимой скорости передачи данных
- UART_INTERR при других ошибках
◆ soft_uart_mode()
int soft_uart_mode | ( | soft_uart_t | уарт , |
uart_data_bits_t | биты данных , | ||
uart_parity_t | четность , | ||
uart_stop_bits_t | стоп_биты | ||
) |
Установка четности, данных и стоповых битов для данного устройства UART.
- Параметры
[in] uart Устройство UART для настройки [in] DATA_BITS Количество битов данных в кадре UART [в] паритет Паритичный режим 1161111111111111111111111111111111111191191191191,9111111111111111111111111111111111111111111111111119111911191111111 ГОДА 61111611116111161111116111111611116111161111111116.BIT. в кадре UART
- Возвращает
- UART_OK в случае успеха
- UART_NOMODE при других ошибках
◆ soft_uart_poweroff()
void soft_uart_poweroff | ( | soft_uart_t | уарт | ) |
Выключите данное устройство UART.
- Параметры
[in] uart устройство UART для отключения питания
◆ soft_uart_poweron()
void soft_uart_poweron | ( | soft_uart_t | уарт | ) |
Включите данное устройство UART.
- Параметры
[in] uart устройство UART для включения
◆ soft_uart_write()
void soft_uart_write | ( | soft_uart_t | уарт , |
константа uint8_t * | данные , | ||
размер_т | лен | ||
) |
Запись данных из заданного буфера в указанное устройство UART.
Эта функция блокируется, так как она вернется только через len Было отправлено
байт из заданного буфера. Способ отправки этих данных зависит от реализации: активное ожидание, управляемое прерыванием, DMA и т. д.
- Параметры
[in] UART Устройство UART для использования для передачи [In] Данные Data Buffer на отправку [в] 16161616161616161616161616161616161616161616161616161616161616161616161616161616111616161616161616161616161116161616161116161616161.
softuart — Документация NodeMCU
Начиная с | Происхождение / Участник | Сопровождающий | Источник |
---|---|---|---|
27.12.2019 | pleningerweb, juancgalvez, crasu, galjonsfigur | галлонфигура | softuart.c |
Модуль SoftUART предлагает последовательные порты с битовым переключением через контакты GPIO.
Предупреждение
Программная реализация последовательного порта может быть ненадежной, и следует ожидать некоторых ошибок приема.
ESP8266 имеет только 1 полный аппаратный порт UART, который используется для программирования чипа и связи с прошивкой NodeMCU. Второй порт предназначен только для передачи. Дополнительную информацию можно найти в документации модуля uart. Этот модуль обеспечивает доступ к большему количеству портов UART и может использоваться для связи с такими устройствами, как модули GSM или GPS. Код основан на проектах esp8266-software-uart и Arduino-esp8266-Software-UART. В настоящее время не поддерживает инвертированную логику последовательных данных или режимы, отличные от 8N1. Важно отметить, что это программная реализация последовательного протокола. Могут быть некоторые прерывания, которые приводят к сбою передачи или приема из-за неправильного времени.
Примечание
SoftUART нельзя использовать на выводе D0.
softuart.setup()
Создает новый экземпляр SoftUART. Обратите внимание, что контакт rx не может использоваться совместно между экземплярами, но контакт tx может.
Синтаксис. Максимальное поддерживаемое значение: 230400.
TxPin
: Tx-контакт SoftUART. Если установлено nil
напишите 9Метод 0577 не будет поддерживаться.
RxPin
: Приемный контакт SoftUART. Если установлено значение nil
on("data"), метод
не будет поддерживаться.Возвращает
экземпляр softuart
.
Пример
-- Создать новый программный UART со скоростью 9600 бод, D2 в качестве вывода Tx и D3 в качестве вывода Rx s = softuart.setup(9600, 2, 3)
softuart.port:on()
Настраивает функцию обратного вызова для получения данных.
Синтаксис
softuart.port:on(событие, триггер, функция(данные))
Параметры
-
событие
: Имя события. В настоящее время поддерживаются только данные -
триггер
: может быть символом или числом. Если символ установлен, функция обратного вызова будет запущена только при получении этого символа. Когда число установлено, функция обратного вызова будет запущена только тогда, когда буфер будет иметь столько символов, сколько число. -
функция(данные)
: Функция обратного вызова. параметрdata
является программным приемным буфером UART.
Возвращает
nil
Пример
-- Создать новый программный UART со скоростью 9600 бод, D2 в качестве вывода Tx и D3 в качестве вывода Rx s = softuart.