Компьютеры Windows Интернет

Последовательный порт. Последовательный порт компьютера Программирование com порта

Особенностью данного порта по сравнению с другими "последовательными" технологиями является факт отсутствия каких-либо временных требований между 2 байтами. Временные требования есть только между битами одного байта (включая старт, стоп и четность), величина, обратная временной паузе между битами одного байта, называется baud rate - скорость передачи. Также в этой технологии отсутствует понятие "пакет".

Другие "последовательные" технологии, такие, как X.25, USB или Ethernet, имеют понятие "пакет", и накладывают жесткие временные требования между всеми битами одного пакета.

По этой причине в терминологии Cisco IOS данный порт назывался async - в отличие от синхронных serial, т.е. X.25. По этой же причине модуль Windows , реализующий PPP поверх данного порта, называется AsyncMac.sys (в стандарте PPP отдельно описана реализация PPP, использующего понятие "пакет", над последовательным портом, этого понятия не имеющим).

Некоторые протоколы связи с индустриальным оборудованием налагают жесткие временные требования между байтами последовательного порта. Такие протоколы крайне сложны в реализации в многозадачных ОС со слабой поддержкой реального времени, такой, как Windows, и потому зачастую требуют MS-DOS и устаревшего ПО почти 20-летней давности на управляющем компьютере.

Назначение

Наиболее часто для последовательного порта персональных компьютеров используется стандарт RS-232C. Ранее последовательный порт использовался для подключения терминала, позже для модема или мыши . Сейчас он используется для соединения с , для связи с аппаратными средствами разработки встраиваемых вычислительных систем , спутниковыми ресиверами, кассовыми аппаратами, а также с приборами систем безопасности объектов.

С помощью COM-порта можно соединить два компьютера, используя так называемый «нуль-модемный кабель» (см. ниже). Использовался со времен MS-DOS для перекачки файлов с одного компьютера на другой, в UNIX для терминального доступа к другой машине, а в Windows (даже современной) - для отладчика уровня ядра.

Достоинством технологии является крайняя простота оборудования. Недостатком является низкая скорость, крупные размеры разъемов, а также зачастую высокие требования к времени отклика ОС и драйвера и высокое количество прерываний (одно на половину аппаратной очереди, т.е. 8 байт).

Разъемы

На материнских платах ведущих производителей (например, Intel) или готовых системах (например, IBM , Hewlett-Packard , Fujitsu Siemens Computers) для последовательного порта принято следующее условное обозначение:

Наиболее часто используются стандартизированные в 1969 году D-образные разъёмы: 9-ти и 25-ти контактные, (DB-9 и DB-25 соответственно). Раньше использовались также DB-31 и круглые восьмиконтактные DIN-8. Максимальная скорость передачи, в обычном исполнении порта, составляет 115 200 бод .

Актуальность

Существуют стандарты на эмуляцию последовательного порта над USB и над Bluetooth (эта технология в значительной степени и проектировалась как «беспроводной последовательный порт»).

Тем не менее программная эмуляция данного порта широко используется и сегодня. Так, например, практически все мобильные телефоны эмулируют внутри себя классический COM-порт и модем для реализации тетеринга - доступа компьютера в Интернет через GPRS/EGDE/3G оборудование телефона. При этом для физического подключения к компьютеру используется USB, Bluetooth или Wi-Fi .

Также программная эмуляция данного порта предоставляется «гостям» виртуальных машин VMWare и Microsoft Hyper-V , основная цель при этом - подключение отладчика уровня ядра Windows к «гостю».

Аппаратура

Разъем имеет контакты:

DTR (Data Terminal Ready - готовность к приёму данных) - выход на компьютере, вход на модеме. Означает готовность компьютера к работе с модемом. Сброс этой линии вызывает почти полную перезагрузку модема в первоначальное состояние, в т.ч. бросание трубки (некоторые управляющие регистры выживают после такого сброса). В UNIX это происходит в случае, если все приложения закрыли файлы на драйвере сериального порта. Мышь использует этот провод для получения питания.

DSR (Data Set Ready - готовность к передаче данных) - вход на компьютере, выход на модеме. Означает готовность модема. Если эта линия находится в нуле - то в ряде ОС становится невозможно открыть порт как файл.

RxD (Receive Data - приём данных) - вход на компьютере, выход на модеме. Поток данных, входящий в компьютер.

TxD (Transmit Data - передача данных) - выход на компьютере, вход на модеме. Поток данных, исходящих из компьютера.

CTS (Clear to Send - готовность передачи) - вход на компьютере, выход на модеме. Компьютер обязан приостановить передачу данных, пока этот провод не будет выставлен в единицу. Используется в аппаратном протоколе управления потоком для предотвращения переполнения в модеме.

RTS (Request to Send - запрос на передачу) - выход на компьютере, вход на модеме. Модем обязан приостановить передачу данных, пока этот провод не будет выставлен в единицу. Используется в аппаратном протоколе управления потоком для предотвращения переполнения в оборудовании и драйвере.

DCD (Carrier Detect - наличие несущей) - вход на компьютере, выход на модеме. Взводится модемом в единицу после установления соединения с модемом с той стороны, сбрасывается в ноль при разрыве связи. Аппаратура компьютера может издавать прерывание при наступлении такого события.

RI (Ring Indicator - сигнал вызова) - вход на компьютере, выход на модеме. Взводится модемом в единицу после обнаружения вызывного сигнала телефонного звонка. Аппаратура компьютера может издавать прерывание при наступлении такого события.

SG (Signal Ground - сигнальная земля) - общий сигнальный провод порта, не является общей землёй , как правило, изолирован от корпуса ЭВМ или модема.

В нуль-модемном кабеле используются две перекрещенные пары: TXD/RXD и RTS/CTS.

Стандартная (со времен оригинальной IBM PC) аппаратура порта называется UART 16550 (в настоящее время включена в SuperIO микросхему на материнской плате вместе с рядом иных устройств). Со времен IBM PC в ней появилась аппаратная очередь байт, которая сильно снижает количество издаваемых устройством прерываний.

Программный доступ к СОМ-порту

UNIX

Для каждого порта в реестре имеется раздел. Эти разделы имеют такие имена:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Serial\Parameters\Serial10000

где последнее значение “Serial10000” - уникальный номер для каждого нового добавленного в систему COM-порта, для второго – “Serial10001” и т.д

Для связи с устройствами, поддерживающими Bluetooth, некоторым программам (например, к таким программам относятся: программа, которая синхронизирует список контактов с мобильным телефоном; программа, которая извлекает координаты GPS из GPS-приемника) на компьютере пользователя требуется COM-порт.

К программам, использующим COM-порты для поддержки связи с помощью технологии беспроводного подключения Bluetooth, непосредственно разработанных фирмой Microsoft, относятся:

  • HotSync, используемый в ручных компьютерах
  • ActiveSync , используемый в карманных ПК

OS/2

Имеющийся драйвер COM.SYS поддерживает только 4 COM-порта, каждый из которых должен иметь свою линию прерываний. Для обслуживания COM-портов с общей линией прерывания необходимо воспользоваться драйвером SIO .

Нуль-модемный кабель

Основная статья: Нуль-модемный кабель

В некоторых случаях возможно применение упрощённого варианта кабеля, в котором задействуются только контакты 2, 3 и 5.

См. также

  • Сигналы последовательных портов

Примечания

Ссылки

  • Перевод руководства по программированию СОМ-порта в POSIX операционных системах
  • Программирование порта на java - позволяет работать из Windows, в отличие от официальных пакетов от Sun.
  • Программирование COM порта на C++ под Windows. Готовая библиотека, исходные тексты, примеры программ.
  • Яшкардин В.Л. Последовательный порт. Программирование COM-порта в Windows и MS-DOS . SoftElectro (2009). Архивировано из первоисточника 8 февраля 2012.

В свое время COM-порт был самым используемым универсальным портом персонального компьютера. Через этот порт к компьютера подключали самые разнообразные устройства:

Другой компьютер

и другие устройства.

Многие устройства имеющие интерфейс USB, при подключении к компьютеру управляются через интерфейс виртуального COM-порта.

Причиной большой популярности COM-порта стала дешевизна провода, ведь в нем может быть всего 3 провода: земля, "туда" и "обратно". История показывает, что внешние соединения лучше делать с помощью последовательного канала связи. Параллельные порты популярны на очень небольших расстояниях. Хотя после появления SATA это утверждение можно подвергнуть сомнению. Идеальная линия связи - это один проводок, как, например, в технологии OneWire. Но и COM-порт для своего времени был достаточно неплох.

Передача данных через COM-порт

Процесс передачи данных по COM"у достаточно прост. Для простоты предположим что данные передаются только в одном направлении. В случае с двунаправленной передачей данных - все симметрично.

Данные передаются блоками по 5 - 8 бит. Обычно используется 7 или 8 байт. Когда передавать нечего, передатчик поддерживает на линии -12 Вольт - логическую единицу. Перед передачей очередной посылки на линии COM-порта появляется сигнал +12 Вольт (логической 0). Этот перепад напряжения сигнализирует удаленному COM-порту о том, что первый бит будет на следующем такте. Далее последовательно посылаются биты данных соответствующего уровня: -12 В = 1, а +12 В = 0. Биты передаются задом-наперед: сначала младший бит - потом старший. Если приемник на удаленной стороне работает на той же частоте, то все биты он примет правильно. Когда все биты передались - передается бит контрольной суммы. После этого линия опять устанавливается в -12 Вольт - происходит передача стоп-бита. Если данных больше нет, то линия так и остается в этом положении. И как только нужно будет еще что-нибудь передать - снова возникает напряжение +12 Вольт и все по новой. Такое относительно высокое напряжение в 12 вольт используется для помехозащищенности связи по COM-порту.

Периоды между посылками разделяются стоп-битом. Вернее сказать не битом, а периодом равным 1, 1.5 или 2 времени на передачу одного бита. С помощью стоп-бита принимающая сторона определяет границы посылок через COM-порт.

История COM-порта

COM-порт - это подмножество интерфейсов UART, которые использовались в США для передачи телеграфных сообщений. Сообщения передавались по 5 бит (максимальная длина "байта" азбуки Морзе). Этот "странный" размер "байта" мы можем наблюдать до сих пор в параметрах настройки передачи данных через COM-порт.

Платы расширения COM

Современные компьютеры не часто имеют отдельный COM-порт. Обычно он есть на материнской плате, но не выведен на заднюю стенку системного блока. Для того чтобы его вывести наружу необходимо установить так называемый выброк COM-порта. Выглядит он следующим образом:

Если на материнской плане нет COM-портов (что очень редко) или их не хватает, то можно установить специальный контроллер - плату расширения. Она устанавливается в PCI или PCI-Express слот.

В случае с ноутбуками (нетбуками) можно воспользоваться USB-переходниками.

Модем и COM-порт

Многие контакты COM-порта используются только модемами. Например, 9-й контакт COM-порта используется модемом, чтобы посылать компьютеру сигнал о том, что кто-то пытается до него дозвониться. Контакт №1 используется модемом для извещения о том, что есть удаленное соединение активно. Обычно управление передачей (контакты 4, 6, 7 и 8) по умолчанию включено для модема.

Работа с COM-портом

При программировании COM-порта на аппаратном уровне используются порты ввода-вывода и таблица прерываний. Для первого COM-порта в IBM PC-совместимых компьютерах зарезервирован порт 3F8 и прерывание IRQ4. Для второго порта: 378 / IRQ3. Хотя эти настройки можно менять в настройках BIOS. На самом деле для каждого COM-порта существует не один порт ввода-вывода, а целых 8.

Иногда приходится решать задачу связи электронного устройства с компьютером, будь то просто обмен данными или удалённое управление. Эта статья описывает, как это можно реализовать, используя последовательный порт. Главным его преимуществом является то, что стандартный программный интерфейс Windows (API) позволяет производить непосредственное управление выходными линиями, давая прямой контроль над ними, и имеет функцию ожидания некоторого события, связанного с COM-портом. Также стандарт RS-232, по которому выполнены COM-порты, допускает подключение и отключение кабелей во время работы устройств (hot plug).

Описание

COM-порт (последовательный порт) – двунаправленный интерфейс, передающий данные в последовательном виде (бит за битом) по протоколу RS-232. Это довольно-таки распространённый протокол, применяемый для связи одного устройства (например, компьютера) с другими посредством проводов длиной до 30м. Уровни логических сигналов здесь отличаются от стандартных: уровень логической единицы – от +5 до +15В, уровень логического нуля – от -5 до -15В, что требует дополнительных преобразований схемы, но обеспечивает хорошую помехоустойчивость.

Рассмотрим 9-пинововый разъём (DB-9M). Ниже представлена его распиновка:

№ вывода Наименование Характер сигнала Сигнал
1 DCD Входной Data carrier detect
2 RxD Выходной Transmit data
3 TxD Входной Receive data
4 DTR Выходной Data terminal ready
5 GND - Ground
6 DSR Входной Data set ready
7 RTS Выходной Request to send
8 CTS Входной Clear to send
9 RI Входной Ring indicator

Больше всего нас будут интересовать пины 2 (передача данных),3 (приём данных) и 5 (земля). Это минимальный набор для возможности двухстороннего общения приборов.

Подробно останавливаться на описании протокола не буду. Для этого есть ГОСТ’ы и т.п. Поэтому мы пойдём дальше и поговорим о том, как же управлять этим зверем.

Применение

Как уже говорилось, уровни ЛС RS-232 отличаются от стандартных уровней ТТЛ. Следовательно, нам необходимо как-то преобразовывать величины напряжений. Т.е. сделать 5В из +15В и 0В из -15В (и наоборот). Один из способов (и, наверное, самый простой) – использование специальной микросхемы MAX232. Она проста в понимании и одновременно может преобразовывать два логических сигнала.

Ниже приведена схема её включения:


Думаю, трудностей быть не должно. Это один из вариантов использования этой микросхемы: передача данных с микроконтроллера на ЭВМ и наоборот. Передаваемый сигнал поступает на ножки Tx IN с одной стороны и на Rx IN с другой. Входные сигналы снимаются с Tx OUT и Rx OUT соответственно.

Программирование

Для начала поговорим о программировании портов на низком уровне. Так будет более правильно. Я очень много нервов потратил, разбираясь с этим интерфейсом, пока не начал вникать в принцип его работы на более низком уровне, нежели простая передача символов. Если будет понятно это, значит и с языками высокого уровня проблем не будет.

Ниже представлены адреса COM-портов, с которыми нам придётся работать:

Название порта Адрес IRQ
COM 1 3F8h 4
COM 2 2F8h 3
COM 3 3E8h 4
COM 4 2E8h 3

Они могут различаться. Установить значения можно в настройках BIOS’а. Это базовые адреса. От них же и будут зависеть адреса регистров, отвечающие за работу портов:

Адрес DLAB Чтение/Запись Аббревиатура Название регистра
+ 0 =0 Write Transmitter Holding Buffer
=0 Read Receiver Buffer
=1 Read/Write Divisor Latch Low Byte
+ 1 =0 Read/Write IER Interrupt Enable Register
=1 Read/Write Divisor Latch High Byte
+ 2 - Read IIR Interrupt Identification Register
- Write FCR FIFO Control Register
+ 3 - Read/Write LCR Line Control Register
+ 4 - Read/Write MCR Modem Control Register
+ 5 - Read LSR Line Status Register
+ 6 - Read MSR Modem Status Register
+ 7 - Read/Write Scratch Register

Первая колонка – адрес регистра относительно базового. Например, для COM1: адрес регистра LCR будет 3F8h+3=3FB. Вторая колонка – DLAB (Divisor Latch Access Bit) бит, определяющий разное назначение для одного и того же регистра.. Т.е. он позволяет оперировать 12-ю регистрами, используя всего 8 адресов. Например, если DLAB=1, то, обращаясь по адресу 3F8h, мы будем устанавливать значение младшего байта делителя частоты тактового генератора. Если же DLAB=0, то, обращаясь по тому же адресу, в этот регистр будет записан передаваемый или принятый байт.

“Нулевой” регистр

Ему соответствуют регистры приёма/передачи данных и установки коэффициента делителя частоты генератора. Как уже было сказано выше, если DLAB=0, то регистр используется для записи принимаемых/передаваемых данных, если же он равен 1, то устанавливается значение младшего байта делителя частоты тактового генератора. От значения этой частоты зависит скорость передачи данных. Старший байт делителя записывается в следующую ячейку памяти (т.е. для порта COM1 это будет 3F9h). Ниже приведена зависимость скорости передачи данных от коэффициента делителя:

Interrupt Enable Register (IER)

Если DLAB=0, то он используется как регистр управления прерываниями от асинхронного адаптера, если DLAB=1, то в нём задаётся старший байт делителя частоты тактового генератора.

Interrupt Identification Register (IIR)

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

Line Control Register (LCR)

Это управляющий регистр.

Бит 7 1 Divisor Latch Access Bit – задание скорости обмена данными
0 Обычнй режим (управление прерываниями, приём/передача данных)
Бит 6 Имитировать обрыв линии (посылает последовательность из нескольких нулей)
Биты 3 – 5 Бит 5 Бит 4 Бит 3 Выбор чётности
X X 0 No Parity
0 0 1 Odd Parity
0 1 1 Even Parity
1 0 1 High Parity (Sticky)
1 1 1 Low Parity (Sticky)
Бит 2 Кол-во стоп-битов
0 1 стоп-бит
1 2 стоп-бита при 6,7 или 8 бит данных или 1.5 стоп-бита при 5 битах данных.
Биты 0 And 1 Бит 1 Бит 0 Число битов данных
0 0 5 бит
0 1 6 бит
1 0 7 бит
1 1 8 бит

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

Стоп-бит означает окончание передачи данных.

Modem Control Register (MCR)

Регистр управления модемом.

Бит Значение
0 Линия DTR
1 Линия RTS.
2 Линия OUT1 (запасная)
3 Линия OUT2 (запасная)
4 Запуск диагностики при входе асинхронного адаптера, замкнутом на его выход.
5-7 Равны 0

Line Status Register (LSR)

Регистр, определяющий состояние линии.

Бит Значение
0 Данные получены и готовы для чтения, автоматически сбрасывается при чтении данных.
1 Ошибка переполнения. Был принят новый байт данных, а предыдущий ещё не был считан программой. Предыдущий байт потерен.
2 Ошибка чётности, сбрасывается после чтения состояния линии.
3 Ошибка синхронизации.
4 Обнаружен запрос на прерывание передачи "BREAK" – длинная строка нулей.
5 Регистр хранения передатчика пуст, в него можно записать новый байт для передачи.
6 Регистр сдвига передатчика пуст. Этот регистр получает данные из регистра хранения и преобразует их в последовательный вид для передачи.
7 Тайм-аут (устройство не связано с компьютером).

Modem Status Register (MSR)

Регистр состояния модема.

Ну вот и всё. Оперируя этими регистрами, можно напрямую общаться с COM-портом, управлять передачей и приёмом данных. Если вам не хочется возиться с памятью, можно воспользоваться уже готовыми компонентами для различных сред программирования: C++, VB, Delphi, Pascal и т.д. Они интуитивно понятны, поэтому, думаю, здесь не стоит заострять на них внимание.

Для связи микроконтроллера с компьютером чаще всего применяют COM-порт. В этой статье мы покажем, как передать команды управления из компьютера и передать данные с контроллера.

Подготовка к работе

Большинство микроконтроллеров обладают множеством портов ввода-вывода. Для связи с ПК наиболее пригоден из них протокол UART. Это протокол последовательной асинхронной передачи данных. Для его преобразования в интерфейс USB на плате есть конвертор USB-RS232 – FT232RL.
Для выполнения примеров их этой статьи вам будет достаточно только Arduino-совместимая плата. Мы используем . Убедитесь, что на вашей плате установлен светодиод, подключенный к 13му выводу и есть кнопка для перезагрузки.

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

int symbol = 33 ; void setup() { Serial. begin(9600 ) ; Serial. println(" ASCII Table ~ Character Map " ) ; } void loop() { Serial. write(symbol) ; Serial. print(" , dec: " ) ; Serial. print(symbol) ; Serial. print(" , hex: " ) ; Serial. print(symbol, HEX) ; Serial. print(" , oct: " ) ; Serial. print(symbol, OCT) ; Serial. print(" , bin: " ) ; Serial. println(symbol, BIN) ; if (symbol = = 126 ) { while (true) { continue ; } } symbol+ + ; }

Переменная symbol хранит код символа. Таблица начинается со значения 33 и заканчивается на 126, поэтому изначально переменной symbol присваивается значение 33.
Для запуска работа порта UART служит функция Serial.begin() . Единственный ее параметр – это скорость. О скорости необходимо договариваться на передающей и приемной стороне заранее, так как протокол передачи асинхронный. В рассматриваемом примере скорость 9600бит/с.
Для записи значения в порт используются три функции:

  1. Serial.write() – записывает в порт данные в двоичном виде.
  2. Serial.print() может иметь много значений, но все они служат для вывода информации в удобной для человека форме. Например, если информация, указанная как параметр для передачи, выделена кавычками – терминальная программа выведет ее без изменения. Если вы хотите вывести какое-либо значение в определенной системе исчисления, то необходимо добавить служебное слово: BIN-двоичная, OCT – восьмеричная, DEC – десятичная, HEX – шестнадцатеричная. Например, Serial.print(25,HEX) .
  3. Serial.println() делает то же, что и Serial.print() , но еще переводит строку после вывода информации.

Для проверки работы программы необходимо, чтобы на компьютере была терминальная программа, принимающая данные из COM-порта. В Arduino IDE уже встроена такая. Для ее вызова выберите в меню Сервис->Монитор порта. Окно этой утилиты очень просто:

Теперь нажмите кнопку перезагрузки. МК перезагрузится и выведет таблицу ASCII:

Обратите внимание на вот эту часть кода:

if (symbol = = 126 ) { while (true) { continue ; } }

Она останавливает выполнение программы. Если вы ее исключите – таблица будет выводиться бесконечно.
Для закрепления полученных знаний попробуйте написать бесконечный цикл, который будет раз в секунду отправлять в последовательный порт ваше имя. В вывод добавьте номера шагов и не забудьте переводить строку после имени.

Отправка команд с ПК

Прежде чем этим заниматься, необходимо получить представление относительного того, как работает COM-порт.
В первую очередь весь обмен происходит через буфер памяти. То есть когда вы отправляете что-то с ПК устройству, данные помещаются в некоторый специальный раздел памяти. Как только устройство готово – оно вычитывает данные из буфера. Проверить состояние буфера позволяет функция Serial.avaliable() . Эта функция возвращает количество байт в буфере. Чтобы вычитать эти байты необходимо воспользоваться функцией Serial.read() . Рассмотрим работу этих функций на примере:

int val = 0 ; void setup() { Serial. begin(9600 ) ; } void loop() { if (Serial. available() > 0 ) { val = Serial. read() ; Serial. print(" I received: " ) ; Serial. write(val) ; Serial. println() ; } }

После того, как код будет загружен в память микроконтроллера, откройте монитор COM-порта. Введите один символ и нажмите Enter. В поле полученных данных вы увидите: “I received: X” , где вместо X будет введенный вами символ.
Программа бесконечно крутится в основном цикле. В тот момент, когда в порт записывается байт функция Serial.available() принимает значение 1, то есть выполняется условие Serial.available() > 0 . Далее функция Serial.read() вычитывает этот байт, тем самым очищая буфер. После чего при помощи уже известных вам функций происходит вывод.
Использование встроенного в Arduino IDE монитора COM-порта имеет некоторые ограничения. При отправке данных из платы в COM-порт вывод можно организовать в произвольном формате. А при отправке из ПК к плате передача символов происходит в соответствии с таблицей ASCII. Это означает, что когда вы вводите, например символ “1”, через COM-порт отправляется в двоичном виде “00110001” (то есть “49” в десятичном виде).
Немного изменим код и проверим это утверждение:

int val = 0 ; void setup() { Serial. begin(9600 ) ; } void loop() { if (Serial. available() > 0 ) { val = Serial. read() ; Serial. print(" I received: " ) ; Serial. println(val, BIN) ; } }

После загрузки, в мониторе порта при отправке “1” вы увидите в ответ: “I received: 110001”. Можете изменить формат вывода и просмотреть, что принимает плата при других символах.

Управление устройством через COM-порт

Очевидно, что по командам с ПК можно управлять любыми функциями микроконтроллера. Загрузите программу, управляющую работой светодиода:

int val = 0 ; void setup() { Serial. begin(9600 ) ; } void loop() { if (Serial. available() > 0 ) { val = Serial. read() ; if (val= = "H" ) digitalWrite(13 , HIGH) ; if (val= = "L" ) digitalWrite(13 , LOW) ; } }

При отправке в COM-порт символа “H” происходит зажигание светодиода на 13ом выводе, а при отправке “L” светодиод будет гаснуть.
Если по результатам приема данных из COM-порта вы хотите, чтобы программа в основном цикле выполняла разные действия, можно выполнять проверку условий в основном цикле. Например.

Вот мы и добрались до COM порта. Но с ним все не так просто как с LPT, и его полноценное использование потребует значительно больших усилий. Главной загвоздкой является и его главное преимущество - передача данных в последовательном виде. Если в LPT байт данных передается по 8-ми линиям по биту на каждую, и состояние каждой линии можно было легко посмотреть, то в COM порту байт данных передается бит за битом по одной линии (относительно земли, конечно) и посмотреть что там передается с помощью одних светодиодов не удастся. Для этого нужно специальное устройство - преобразователь потока последовательных данных в парраллельный, т.н. USART (Universal Synchronous/Asynchronous Receiver Transmitter). Например, он есть в составе материнской платы компьютера, снабженного COM портом, в любом более мение серьезном микроконтроллере.


Надеюсь, вы еще пали духом в освоении COM порта. Все не так уж и мрачно. Некоторые результаты можно получить и без USART. Сформулируем задачу, которую реализуем на начальном этапе работы с COM портом:


"Хочу что бы к компьютеру через COM порт подключался светодиод. Запускаю программу. Далаю какое-то действие в этой программе, светодиод загорается, делаю другое - светодиод тухнет."


Задача довольно специфичная (с учетом того, что USART не используется) и является чистой "самопальщиной", но вполне реализуема и работоспособна. Давайте приступим к ее реализации.


1. COM порт

Опять берем системный блок вашего ПК и смотрим в тыловую часть. Примечаем там 9-ти штырьковй разъем - это и есть COM порт. Реально их может быть неколько (до 4-х). На моем ПК установлено два COM порта (см. фото).


2. Удлинитель COM порта


3. Аппаратная часть

С аппаратной частью нам тоже придется "повозиться", в том смысле что она будет сложнее чем с первым устройством для LPT порта. Дело в том что протокол RS-232 по которому идет обмен данными в COM порту, имеет несколько отличное соотношение логическое состояние - напряжение. Если обычно это логический 0 0 В, логическая 1 +5 В, то в RS-232 это соотношение следующее: логический 0 +12 В, логическая 1 -12 В.

И например, получив -12 В не сразу понятно что с этим напряжением делать. Обычно проводят преобразование уровней RS-232 в ТТЛ (0, 5 В). Самый простой вариант - стабилитроны. Но я предлагаю сделать этот преобразователь на специальной микросхеме. Называется она MAX232.

Теперь давайте посмотрим, а какие сигналы из COM порта мы можем посмотреть на светодиодах? В действительности, в COM порту есть аж 6 независимых линий, представляющих интерес для разработчика устройств сопряжения. Две из них пока для нас недоступны - линии по передаче последовательных данных. А вот оставшиеся 4 предназначены для управления и индикации процесса передачи данных и мы сможем "передалать" их под свои нужды. Две из них предназначены для управления со стороны внешнего устройства и мы их пока трогать не будем, а вот последние две оставшиеся линии мы сейчас и поиспользуем. Они называются:

  • RTS - Запрос на передачу. Линия взаимодействия, которая показывает, что компьютер готов к приему данных.
  • DTR - Компьютер готов. Линия взаимодействия, которая показывает, что компьютер включен и готов к связи.

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

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

А вот ее практичекая реализация. Я думаю вы меня простите, что я сделал ее в таком стремном макетном варианте, ибо делать плату для такой "высоко продуктивной" схемы не хочется.


4. Программная часть

Тут все попроще. Давайте создадим Windows приложение в Microsoft Visual C++ 6.0 на основе MFC для управления двумя линиями взаимодействия COM порта. Для этого создаем новый проект MFC и указываем ему имя, например, TestCOM . Далее выбираем вариант построения на основе диалога.

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

Class CTestCOMDlg: public CDialog { // Construction public: CTestCOMDlg(CWnd* pParent = NULL); // standard constructor HANDLE hFile;

Чтобы наша программа могла упрявлять линиями COM порта, его надо сначала открыть. Напишем код, ответственный за открытие порта при загрузке программы.

HFile = CreateFile("COM2", GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0,NULL); if(hFile==INVALID_HANDLE_VALUE) { MessageBox("Не удалось открыть порт!", "Ошибка", MB_ICONERROR); } else { MessageBox("Порт успешно открыт", "Ok", MB_OK); }

С помощью стандарной функции Win API CreateFile() открываем COM-порт COM2 . Далее проверяем успешность открытия с выводом информационного сообщения. Вот тут надо сделать важное замечание: COM2 - это в моем компьютере, а на Вашем компьютере Вы могли подключить его к другому COM порту. Соответственно, его имя нужно изменить на то, кокай порт Вы используете. Посмотреть, какие номера портов присутствуют на Вашем компьютере, можно так: Пуск -> Настройка -> Панель управления -> Система -> Оборудование -> Диспетчер устройств -> Порты (COM и LPT) .

В итоге, функция CTestCOMDlg::OnInitDialog() , расположенная в файле TestCOMDlg.cpp , класса нашего диалога должна принять вид:

BOOL CTestCOMDlg::OnInitDialog() { CDialog::OnInitDialog(); // Add "About..." menu item to system menu. // IDM_ABOUTBOX must be in the system command range. ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX); ASSERT(IDM_ABOUTBOX AppendMenu(MF_SEPARATOR); pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu); } } // Set the icon for this dialog. The framework does this automatically // when the application"s main window is not a dialog SetIcon(m_hIcon, TRUE); // Set big icon SetIcon(m_hIcon, FALSE); // Set small icon // TODO: Add extra initialization here hFile = CreateFile("COM2", GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0,NULL); if(hFile==INVALID_HANDLE_VALUE) { MessageBox("Не удалось открыть порт!", "Оштбка", MB_ICONERROR); } else { MessageBox("Порт успешно открыт", "Ok", MB_OK); } return TRUE; // return TRUE unless you set the focus to a control }

Теперь добавим обработчики кнопок управления линиями. Я дал им соответствующие имена: функция, которая устанавливает еденицу на линии DTR - OnDTR1(), 0 - OnDTR0(). Для линии RTS соответственно аналогичным образом. Напомню, что обработчик создается при двойном щелчке на кнопке. В итоге, эти четыре функции должны принять вид:

Void CTestCOMDlg::OnDTR1() { // TODO: Add your control notification handler code here EscapeCommFunction(hFile, 6); } void CTestCOMDlg::OnDTR0() { // TODO: Add your control notification handler code here EscapeCommFunction(hFile, 5); } void CTestCOMDlg::OnRTS1() { // TODO: Add your control notification handler code here EscapeCommFunction(hFile, 4); } void CTestCOMDlg::OnRTS0() { // TODO: Add your control notification handler code here EscapeCommFunction(hFile, 3); }

Поясню немного как они работают. Как видно, внитри себя они содержат вызов одной и той же Win API функции EscapeCommFunction() с двумя параметрами. Первый из них - это хэндл (HANDLE) на открытый порт, второй - специальный код действия, соответствующий необходимому состоянию линии.

Все, комилируем, запускаем. Если все хорошо, должны увидеть сообщение об успешном открытии порта. Далее, нажатием соответствующих кнопок мигаем светодиодами, подключенными к COM порту.

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