Как настроить скорость ком порта

Работа с последовательными портами — работа с COM портами

В настоящее время существует множество устройств, которые обмениваются с компьютером информацией через последовательный порт (COM1, COM2) по протоколу RS-232. Причем такие устройства разрабатывают до сих пор и, я уверен, будут разрабатывать и в дальнейшем. Ведь несмотря на недостатки такой связи: медленная скорость обмена информацией, ограничение на длину соединительных линий — существует и немало достоинств: программная поддержка протокола RS-232 и ему подобных многими периферийными устройствами, специализированными микросхемами, низкая стоимость, минимальное количество соединительных проводов, простота.

Но, как это ни странно, информации по работе с последовательными портами в программах под Win32 очень мало. Материал этой статьи основан на статье Олега Титова Работа с коммуникационными портами (COM и LPT) в программах для Win32 — ознакомиться с ней можно по адресу. Автором очень подробно описаны функции для работы с коммуникационными портами, основное внимание уделено синхронному обмену информацией. Мы же рассмотрим вариант обмена между компьютером и периферийным устройством в асинхронном режиме (как правило, используемом наиболее часто) — причем для простейшего соединения по трем проводам, без использования управляющих сигналов. Таким же образом можно организовать связь между двумя компьютерами (хотя бы для проверки работы своей программы).

Начнем с главного: с последовательными портами в Win32 работают как с файлами. Причем используют только функции API Win32.

Начинается работа с открытия порта как файла, причем для
асинхронного режима ввода-вывода возможен только один вариант:

HANDLE handle = CreateFile(«COM1», GENERIC_READ |
GENERIC_WRITE, NULL, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED,
NULL);

Других вариантов быть не может, поэтому не будем рассматривать
параметры этой функции подробно, единственное, что можно сделать —
это заменить “COM1” на “COM2”. Больше последовательных портов на
компьютере, как правило, нет. При успешном открытии порта функция
возвращает дескриптор handle, с которым и будем работать в
дальнейшем. При неудачном открытии порта функция вернет значение
INVALID_HANDLE_VALUE.

Получив доступ к порту, необходимо его настроить — задать
скорость обмена, формат данных, параметры четности и т. д. Основные
параметры последовательного порта задают структуры DCB и
COMMTIMEOUTS. Структура DCB содержит основные параметры порта и,
кроме этого, довольно много специфических полей.

typedef struct _DCB <

DWORD DCBlength; // sizeof(DCB)

DWORD BaudRate; // current baud rate

DWORD fBinary:1; // binary mode, no EOF check

DWORD fParity:1; // enable parity checking

DWORD fOutxCtsFlow:1; // CTS output flow control

DWORD fOutxDsrFlow:1; // DSR output flow control

DWORD fDtrControl:2; // DTR flow control type

DWORD fDsrSensitivity:1; // DSR sensitivity

DWORD fTXContinueOnXoff:1; // XOFF continues Tx

DWORD fOutX:1; // XON/XOFF out flow control

DWORD fInX:1; // XON/XOFF in flow control

DWORD fErrorChar:1; // enable error replacement

DWORD fNull:1; // enable null stripping

DWORD fRtsControl:2; // RTS flow control

DWORD fAbortOnError:1; // abort reads/writes on error

DWORD fDummy2:17; // reserved

WORD wReserved; // not currently used

WORD XonLim; // transmit XON threshold

WORD XoffLim; // transmit XOFF threshold

BYTE ByteSize; // number of bits/byte, 4-8

BYTE Parity; // 0-4=no,odd,even,mark,space

Читайте также:  Не работает блок управления стеклоподъемниками рено флюенс

BYTE StopBits; // 0,1,2 = 1, 1.5, 2

char XonChar; // Tx and Rx XON character

char XoffChar; // Tx and Rx XOFF character

char ErrorChar; // error replacement character

char EofChar; // end of input character

char EvtChar; // received event character

WORD wReserved1; // reserved; do not use

Мы рассмотрим назначение только некоторых основных полей этой
структуры, используемых для нашего случая ввода-вывода, так как
многие поля можно заполнить значениями “по умолчанию”, пользуясь
функцией GetCommState:

Таким образом, нет необходимости вникать во все тонкости
структуры. После этого некоторые поля DCB все же придется заполнить
вручную, а именно:

BaudRate — скорость передачи данных. Возможно указание
следующих констант: CBR_110, CBR_300, CBR_600, CBR_1200, CBR_2400,
CBR_4800, CBR_9600, CBR_14400, CBR_19200, CBR_38400, CBR_56000,
CBR_57600, CBR_115200, CBR_128000, CBR_256000. Можно просто указать
соответствующее число, например 9600, но предпочтительнее все-таки
пользоваться символическими константами.

ByteSize — определяет число информационных бит в
передаваемых и принимаемых байтах. Может принимать значение 4, 5, 6,
7, 8.

Parity — определяет выбор схемы контроля четности. Данное
поле должно содержать одно из следующих значений:


  • EVENPARITY — дополнение до четности;
  • MARKPARITY — бит четности всегда равен 1;
  • NOPARITY — бит четности отсутствует;
  • ODDPARITY — дополнение до нечетности;
  • SPACEPARITY — Бит четности всегда 0.

StopBits — задает количество стоповых бит. Поле может
принимать следующие значения:


  • ONESTOPBIT — один стоповый бит;
  • ONE5STOPBIT — полтора стоповых бита (практически не
    используется);
  • TWOSTOPBIT — два стоповых бита.

После того как все поля структуры DCB заполнены, необходимо
произвести конфигурирование порта, вызвав функцию SetCommState:

В случае успешного завершения функция вернет отличное от нуля
значение, а в случае ошибки — нуль.

Второй обязательной структурой для настройки порта является
структура COMMTIMEOUTS. Она определяет параметры временных задержек
при приеме-передаче. Вот описание этой структуры:

typedef struct _COMMTIMEOUTS <

Поля структуры COMMTIMEOUTS имеют следующие значения:


  • ReadIntervalTimeout — максимальное временной промежуток
    (в миллисекундах), допустимый между двумя считываемыми с
    коммуникационной линии последовательными символами. Во время
    операции чтения временной период начинает отсчитываться с момента
    приема первого символа. Если интервал между двумя
    последовательными символами превысит заданное значение, операция
    чтения завершается и все данные, накопленные в буфере, передаются
    в программу. Нулевое значение данного поля означает, что данный
    тайм-аут не используется.
  • ReadTotalTimeoutMultiplier — задает множитель (в
    миллисекундах), используемый для вычисления общего тайм-аута
    операции чтения. Для каждой операции чтения данное значение
    умножается на количество запрошенных для чтения символов.
  • ReadTotalTimeoutConstant — задает константу (в
    миллисекундах), используемую для вычисления общего тайм-аута
    операции чтения. Для каждой операции чтения данное значение
    плюсуется к результату умножения ReadTotalTimeoutMultiplier на
    количество запрошенных для чтения символов. Нулевое значение полей
    ReadTotalTimeoutMultiplier и ReadTotalTimeoutConstant означает,
    что общий тайм-аут для операции чтения не используется.
  • WriteTotalTimeoutMultiplier — задает множитель (в
    миллисекундах), используемый для вычисления общего тайм-аута
    операции записи. Для каждой операции записи данное значение
    умножается на количество записываемых символов.
  • WriteTotalTimeoutConstant — задает константу (в
    миллисекундах), используемую для вычисления общего тайм-аута
    операции записи. Для каждой операции записи данное значение
    прибавляется к результату умножения WriteTotalTimeoutMultiplier на
    количество записываемых символов. Нулевое значение полей
    WriteTotalTimeoutMultiplier и WriteTotalTimeoutConstant означает,
    что общий тайм-аут для операции записи не используется.

Немного поподробнее о тайм-аутах. Пусть мы считываем из порта 50
символов со скоростью 9 600 бит/с. Если при этом используется 8 бит
на символ, дополнение до четности и один стоповый бит, то на один
символ в физической линии приходится 11 бит (включая стартовый бит).
Значит, 50 символов на скорости 9 600 бит/с будут приниматься

или примерно 57,3 миллисекунды, при условии нулевого интервала
между приемом последовательных символов. Если же интервал между
символами составляет примерно половину времени передачи одного
символа, т. е. 0,5 миллисекунд, то время приема будет

или примерно 82 миллисекунды. Если в процессе чтения прошло более
82 миллисекунд, то мы вправе предположить, что произошла ошибка в
работе внешнего устройства и можем прекратить считывание, тем самым
избежав зависания программы. Это и есть общий тайм-аут операции
чтения. Аналогично существует и общий тайм-аут операции записи.

Формула для вычисления общего тайм-аута операции, например,
чтения, выглядит так:

NumOfChar x ReadTotalTimeoutMultiplier +
ReadTotalTimeoutConstant

где NumOfChar — число символов, запрошенных для операции чтения.

В нашем случае тайм-ауты записи можно не использовать и
установить их равными нулю.

После заполнения структуры COMMTIMEOUTS, необходимо вызвать
функцию установки тайм-аутов:

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

Допустим, вы обмениваетесь с внешним устройством пакетами
информации размером 1024 байта, тогда разумным размером буферов
будет значение 1200. Функция SetupComm интересна тем, что она может
просто принять ваши размеры к сведению, внеся свои коррективы, либо
вообще отвергнуть предложенные вами размеры буферов — в таком случае
эта функция завершится ошибкой.

Приведу пример открытия и конфигурирования последовательного
порта COM1. Для краткости — без определения ошибок. В данном примере
порт открывается для работы со скоростью 9 600 бит/c, используется 1
стоповый бит, бит четности не используется:

handle = CreateFile(«COM1», GENERIC_READ | GENERIC_WRITE,
NULL, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);

SetupComm(handle, SizeBuffer, SizeBuffer);

Источник

Скорость передачи данных через UART

UART — это приемопередатчик на котором базируется RS-232 и другие подобные интерфейсы.

Скорость работы UART не означает скорость передачи данных, так как вместе с полезными данными UART передает служебные:

  • стартовый бит,
  • стоповый бит,
  • бит четности.

Скорость работы UART измеряется в бодах, а скорость передачи полезных данных — в битах и байтах в секунду.

Скорость передачи данных в битах в секунду:

  • VUART — скорость UART (например: 9600, 115200), бод;
  • d — количество бит данных;
  • s — количество стоповых бит;
  • p — количество бит четности, p = 1 если бит четности присутствует, или p = 0 если бит четности отсутствует;
  • единица в знаменателе отражает наличие стартового бита.

Та же формула для расчетов:

С учетом, что один байт содержит 8 бит, из предыдущей формулы можно получить скорость передачи полезных данных в байтах в секунду:

Для работы UART чаще всего используется режим 8-N-1 при котором d = 8, p = 0, s = 1. Для этого режима скорость передачи полезных данных равна:

Отсюда следует, что КПД для такого режима составляет 80 %.

В таблице ниже приводится КПД для разных режимов работы UART:

d , бит p , бит s , бит КПД, %
5 0 1 71
5 0 1,5 67
5 0 2 62
5 1 1 62
5 1 1,5 59
5 1 2 56
6 0 1 75
6 0 1,5 71
6 0 2 67
6 1 1 67
6 1 1,5 63
6 1 2 60
7 0 1 78
7 0 1,5 74
7 0 2 70
7 1 1 70
7 1 1,5 67
7 1 2 64
8 0 1 80
8 0 1,5 76
8 0 2 73
8 1 1 73
8 1 1,5 70
8 1 2 67
9 0 1 82
9 0 1,5 78
9 0 2 75
9 1 1 75
9 1 1,5 72
9 1 2 69

Не часто поддерживаемый режим 9-N-1 дает наилучший результат (82 %), но отличающийся от 8-N-1 лишь на 2 %.

Существует ряд стандартных скоростей: 300, 600, 1 200, 2 400, 4 800, 9 600, 19 200, 38 400, 57 600, 115 200, 230 400, 460 800 и 921 600 бод.

Максимальная скорость классического последовательного порта (COM-порта) компьютера равна 115 200 бодам.

Между порциями полезных данных может быть ненулевая задержка, что уменьшает скорость передачи данных. Если не учитывать эту задержку, то количество секунд требуемых для передачи D байт рассчитывается по следующей формуле:

Например, время передачи 1 МБ (1 048 576 байт) со скоростью 9 600 бод в режиме 8-N-1 составляет 18 минут и 12 секунд, а при скорости 115 200 бод — 1 минуту 31 секунду.

Сравнительная таблица скоростей передачи данных для стандартных скоростей UART:

Скорость UART, бод Скорость передачи данных, байт/с Время передачи 1 МБ, час:мин:сек
Данные: 8 бит
Стоп: 1 бит
Четность: нет
Данные: 8 бит
Стоп: 1 бит
Четность: да
Данные: 8 бит
Стоп: 1 бит
Четность: нет
Данные: 8 бит
Стоп: 1 бит
Четность: да
300 30 27,3 09:42:33 10:40:48
600 60 54,5 04:51:16 05:20:24
1 200 120 109,1 02:25:38 02:40:12
2 400 240 218,2 01:12:49 01:20:06
4 800 480 436,4 00:36:25 00:40:03
9 600 960 872,7 00:18:12 00:20:01
19 200 1 920 1 745,5 00:09:06 00:10:01
38 400 3 840 3 490,9 00:04:33 00:05:00
57 600 5 760 5 236,4 00:03:02 00:03:20
115 200 11 520 10 472,7 00:01:31 00:01:40

В настоящий момент COM-порт компьютера вытеснен USB. Тем не менее UART широко используется в различных приборах. Для связи их с компьютером существуют преобразователи USB-UART. И любой микроконтроллер имеет один или более UARTов. В таблице ниже приводится информация о максимальных скоростях работы различных микросхем.

Микросхема Назначение микросхемы Максимальная скорость UART, Мбод Максимальная скорость передачи данных в режиме 8-N-1, Байт/с
CP2101 Преобразователь USB-UART 0,9216 92 160
CP2102/3/9/10 Преобразователь USB-UART 1 100 000
CP2104/5/8 Преобразователь USB-UART 2 200 000
FT232R Преобразователь USB-UART 3 300 000
FT232H Преобразователь USB-UART 12 1 200 000
STM32F7 Микроконтроллер 27 2 700 000
STM32F4 Микроконтроллер 11,25 1 250 000

Небольшие скорости обусловлены тем, что UART тактируется с частотой во много раз превышающей скорость его работы. Чем больше тактов на один бит данных, тем надежнее связь. Чаще всего на 1 бит приходится 16 тактов. Кроме этого встречаются микросхемы поддерживающие 4, 8 и 10 тактов на бит.

Автором был разработан переходник USB — UART с 16 портами UART, которые могут работать на скорости 12 Мбод.

Источник

Читайте также:  Сломалась чаша от комбайна
Оцените статью