Опубликовано

Последовательный обмен данными с использованием двух протоколов последовательной связи: TTL Serial и USB

По материалам книги Т.Иго «Умные вещи: Arduino, датчики и сети для связи устройств: Пер. с англ. 3-е изд.»  (глава 2 «Простейшая сеть»)

Умные вещи: Arduino

Устанавливаем соединение: нижние уровни

Мы уже знакомы с одним примером последовательного обмена данными — между микроконтроллером и персональным компьютером. В частности, в главе 1 мы подключили микроконтроллерный модуль к персональному компьютеру через порт USB. Это подключение является примером асинхронного последовательного обмена данными с использованием двух протоколов последовательной связи: TTL Serial и USB.

Первый из них — это протокол, понимаемый микроконтроллером, и называется он последовательный ТТЛ (TTL[1] Serial). Этот протокол можно разделить на следующие концептуальные уровни:

  • Физический. Определяет контакты, используемые контроллером для обмена данными. В модуле Arduino данные принимаются на контакт, обозначенный RX (от Receive, прием), а передаются с контакта, обозначенного TX (от Transmit, передача).
  • Электрический. Определяет напряжения для представления битов данных. В некоторых микроконтроллерах применяется напряжение 3,3 В, в других — 5 В.
  • Логический. Высокий уровень напряжения (3,3 или 5 В) представляет логическое значение 1, а низкий (0 В) — логическое значение 0.
  • Уровень данных. Обмен данными обычно осуществляется со скоростью 9600 битов в секунду. Для представления одного символа требуется один байт, который содержит 8 битов данных, а также стартовый и стоповый биты (которые мы никогда не будем использовать).
  • Уровень приложений. На этом уровне мы отправляем один байт от ПК на микроконтроллер, который обрабатывает его и возвращает один байт на ПК.

Но это еще не все. Импульсы напряжения не идут на ПК напрямую. Сначала они поступают на TTL/USB микросхему на плате, которая преобразовывает последовательные TTL-сигналы в последовательные USB-сигналы. На некоторых микроконтроллерных платах — например, на Arduino Uno, преобразователь USB сигналов в сигналы ТТЛ реализован в виде отдельной микросхемы. На других же — например, на MKR1000 и Arduino 101, эта функциональность встроена в микросхему микроконтроллера.

Обработка преобразованных в формат USB сигналов осуществляется с использованием соответствующего протокола USB[2], который во многом отличается от протокола последовательного обмена TTL. Он разбивается на следующие концептуальные уровни:

  • Физический. Шина USB состоит из двух проводов для передачи данных: Data+ и Data– и двух проводов питания (+5 В и общего).
  • Электрический. Сигнал на линии Data– всегда противоположен сигналу на линии Data+, в результате чего сумма напряжений этих сигналов всегда равна нулю. Эта особенность используется приемником для проверки на наличие ошибок электрического сигнала — для этого он складывает напряжения обеих этих линий. Если полученная сумма не равна нулю, приемник отбрасывает такой сигнал.
  • Логический. Логическое значение 1 представляется сигналом напряжения +5 В (на линии Data+) или –5 В (на линии Data–), а логическое значение 0 — сигналом напряжения 0 В.
  • Уровень данных. Уровень данных модели протокола USB более сложный, чем соответствующий уровень протокола последовательного обмена ТТЛ. В USB скорость обмена данными может достигать 480 мегабит в секунду. Один символ представляется одним байтом, который содержит 8 битов данных, а также стартовый и стоповый биты. Несколько устройств USB под управлением ПК могут использовать для обмена данными одну и ту же пару проводов (набор проводов для обмена сигналами называется шиной). Поскольку к одной шине может быть подсоединено несколько устройств, операционная система присваивает каждому из этих устройств однозначный адрес и обеспечивает обмен данными между каждым подсоединенным к шине устройством и его соответствующим приложением на компьютере.
  • Уровень приложений. На уровне приложения преобразователь USB/TTL-Serial на плате Arduino отправляет операционной системе компьютера несколько байтов, чтобы идентифицировать себя. Операционная система использует эти байты для того, чтобы сопоставить плату с программой ее драйвера, который другие программы могут использовать для обмена данными с этим устройством.

Все это управление прозрачно для пользователя, так как контроллер USB компьютера передает ему только те байты, которые предназначены для него. Микросхема преобразователя USB/TTL-Serial на плате Arduino представляет себя операционной системе компьютера в качестве последовательного порта и отправляет данные через разъем USB с выбранной пользователем скоростью (9600 битов в секунду — как в примере из главы 1).

 

Кабель-переходник USB/TTL-Serial компании FTDI

 

Рис. 2.4. Кабель-переходник USB/TTL-Serial компании FTDI

Распиновка разъема TTL

Рис. 2.5. Распиновка разъема TTL кабеля USB/TTL-Serial компании FTDI. Кроме линий передачи, приема и питания он также имеет линии для аппаратного управления обменом данных: RTS (Request-to-send, запрос на передачу) и CTS (Clear-to-send, готовность к передаче). Некоторые устройства используют эти линии для управления потоком последовательных данных

Есть и еще один протокол — если вы используете микроконтроллерный модуль BASIC Stamp или другой микроконтроллерный модуль с интерфейсом иным, чем USB, он, скорее всего, оснащен 9-контактным разъемом для подключения к компьютеру или к адаптеру USB/RS-232 (распиновка разъемов USB и RS-232 показана на рис. 2.6). Этот разъем называется DB-9 или D-sub-9 и является стандартным разъемом для другого последовательного протокола: RS-232. Протокол RS-232 был стандартом для последовательного интерфейса компьютеров до протокола USB и все еще встречается на некоторых специализированных периферийных устройствах. Этот протокол состоит из следующих концептуальных уровней:

  • Физический. Данные в разъеме RS-232компьютера принимаются на контакт 2, а передаются с контакта 3. Контакт 5 — «земля».
  • Электрический. Данные в стандарте RS-232 передаются двумя уровнями напряжения: от +3 В до +25 В и от –3 В до –25 В.
  • Логический. Высокий уровень напряжения (от +3 В до +25 В) представляет логическое значение 0, а низкий (от –3 В до –25 В) — логическое значение 1. Как можно видеть, эта схема построена на основе отрицательной (или инвертированной) логики.
  • Уровень данных. Такой же, как и в протоколе TTL, — 8-битовый байт данных с дополнительными стартовым и стоповымбитами.

Распиновка разъемов: USB и RS-232

Рис. 2.6. Распиновка разъемов: USB и RS-232

 

Спрашивается, как же подключать некоторые микроконтроллеры — например, BASIC Stamp, непосредственно к последовательному порту RS-232? Поскольку микроконтроллеры обычно не могут создавать отрицательные напряжения, для преобразования выходных сигналов ТТЛ микроконтроллера в уровни RS-232 обычно используется отдельная специальная микросхема. Протокол RS-232 намного проще, чем протокол USB, но, к сожалению, он, по большому счету, сильно устарел. Большинство современных микроконтроллеров оснащены встроенным преобразователем USB/TTL-Serial.

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

Преобразователи USB/Serial

Большинство современных электронных модулей, с которыми вам придется иметь дело, будут, скорей всего, оснащены каким-либо последовательным интерфейсом для взаимодействия с микроконтроллерами. Самым распространенным из таких интерфейсов является последовательный TTL-интерфейс — TTL-Serial. Например, большинство модулей системы GPS[5] (с одним из которых мы познакомимся в главе 8) оснащены интерфейсом TTL-Serial.  Для любого, кто интересуется созданием современных электронных устройств, преобразователь USB/TTL-Serial станет одним из самых необходимых инструментов.

На рынке доступен ряд микросхем преобразователя USB/Serial. Одной из наиболее популярных является микросхема FT232RL, изготавливаемая уже упомянутой ранее компанией FTDI. Но основе этой микросхемы компания делает кабель-переходник, другие компании также используют эту микросхему для изготовления плат-преобразователей. Кабель-переходник компании FTDI (см. рис. 2.4) приобрел такую популярность, что его распиновка (см. рис. 2.5) была принята в качестве де-факто стандарта на рынке любительской электроники  и используется во многих устройствах.

Кроме кабеля-преобразователя компании FTDI, преобразовательные платы изготавливают такие компании как Adafruit, SparkFun, Parallax и ряд других. Микросхемой FT232RL также оснащаются многие устройства, включая адаптеры XBee компании Digi и платы-клоны Arduino RedBoard компании SparkFun.

Эта микросхема удобна тем, что она может обрабатывать последовательные TTL-сигналы разных напряжений:  5 В и 3,3 В. Компания SparkFun изготавливает отдельные версии плат для каждого напряжения,  а у платы FTDI Friend компании Adafruit на тыльной стороне предусмотрен ряд перемычек, перепаивая которые можно менять рабочее напряжение контактов для приема и передачи последовательных сигналов. Кроме того, эта плата также способна работать с уровнями напряжения сигналов RS-232. Для работы с RS-232 предназначена  и адаптерная плата компании Parallax, оснащенная к тому же разъемом DB-9.

Использование адаптера USB/TTL-Serial не представляет собой ничего сложного. Контакт передачи (TX) этого адаптера подсоединяется к контакту приема (RX) устройства и наоборот. Общий («земляной») контакт платы подключается к соответствующему контакту устройства, а при питании устройства от адаптерной платы контакт питания VCC платы подключается к контакту питания устройства. Прежде чем запитывать устройство от адаптера, необходимо убедиться в том, что устройство может работать на уровне напряжения, подаваемого адаптером. Напряжение питания большинства адаптеров USB/TTL-Serial составляет 5 В, что может повредить устройства с питанием 3,3 В. В главе 1 мы узнали, как с помощью адаптера USB/TTL-Serial компании FTDI подключиться через монитор порта к плате Raspberry Pi (см. рис. 1.17). Но в том случае плата микроконтроллера не запитывалась от адаптерной платы.

Чтобы использовать с компьютером любой из адаптеров USB/Serial, на компьютер нужно установить драйверы микросхемы этого адаптера. Качество работы адаптера USB/TTL-Serial во многом зависит от качества его драйвера. Драйверы более дешевых адаптеров обычно совместимы с более узким диапазоном платформ. Поэтому имеет смысл немного переплатить, но приобрести устройство с доступными, качественными и многоплатформенными драйверами. В этом отношении особенно выделяется компания FTDI —драйверы от этой компании всегда вовремя обновляются для поддержки текущих версий Windows, macOS и различных дистрибутивов Linux.

Но кроме компании FTDI, адаптеры USB/TTL-Serial изготавливаются и другими компаниями —  например, компаниями Prolific (адаптер PL2303), Silicon Labs (адаптер CP2102), Jiangsu Heng Qin (адаптер CP340) и другими. Драйверы для упомянутых адаптерных плат этих компаний можно загрузить со следующих веб-сайтов:

  • ftdichip.com/FTDrivers.htm (FTDI);
  • silabs.com/products/mcu/Pages/USBtoUARTBridgeVCPDrivers.aspx (Silicon Labs);
  • prolific.com.tw/US/Show-Product.aspx?pcid=41 (Prolific);
  • wch.cn/download/CH341SER_ZIP.html (Jiangsu Heng Qin).

В плате Arduino Uno в качестве адаптера USB/TTL-Serial используется микроконтроллер общего назначения Atmel 16U2, запрограммированный под эту задачу. Для этого адаптера не требуются драйверы под macOS и Linux, а драйверы USB для Windows устанавливаются автоматически установщиком Windows. Исходный код адаптера USB/TTL-Serial для Arduino Uno можно загрузить из каталога hardware/arduino/avr/firmwares/atmegaxxu2 репозитория https://github.com/arduino, а дополнительную информацию о конструкциях устройств USB вы найдете на веб-сайте www.usb.org/developers/usbfaq.

При использовании адаптера USB/TTL-Serial для программирования микроконтроллера вам, вероятно, нужно будет также задействовать выводы CTS (clear-to-send, готовность к передаче) и RTS (request-to-send, запрос на передачу). Большинство микроконтроллеров, полагающихся на адаптеры USB/TTL-Serial, — такие, как адаптерная плата Huzzah! на микросхеме ESP8266 компании Adafruit или плата ESP8266 Thing компании SparkFun, оснащены контактами для этих выводов, так что вам не нужно беспокоиться об этом. Дополнительную информацию по использованию адаптеров USB/TTL-Serial для программирования микроконтроллеров ищите в руководстве по программированию вашей платы.

Использование платы Arduino в качестве адаптера USB/TTL-Serial

Если у вас нет под рукой отдельного адаптера USB/TTL-Serial, вместо него можно воспользоваться совместимой с Arduino платой, запрограммировав ее должным образом.

В частности, для этой цели подойдут платы MKR1000 или Arduino 101. Обе платы используют одинаковые процессоры, оснащенные встроенными средствами работы с USB, и последовательные порты этих плат, отображаемые в мониторе порта, подключены непосредственно к процессору. Для обращения к выводам TX (передача) и RX (прием) платы обычно используется объект Serial1. Далее приводится скетч для реализации этой задачи. В нем вывод передачи USB перенаправляется на вывод приема (RX) платы, а вывод приема USB — на вывод передачи (TX) платы. Таким образом, любая микроконтроллерная плата на микроконтроллере со встроенными средствами работы с USB превращается в адаптер USB/TTL-Serial.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
void setup() {
 
// инициализируем оба последовательные подключения:
Serial.begin(9600);  // USB
 
Serial1.begin(9600); // TTL
}
 
 
 
void loop() {
 
// считываем RX TTL, отправляем на USB:
 
if (Serial1.available()) {
 
char c = Serial1.read();
 
Serial.write(c);
 
}
 
 
 
// считываем USB, отправляем на TX TTL:
 
if (Serial.available()) {
 
char c = Serial.read();
 
Serial1.write(c);
 
}
 
}

Микроконтроллеры более старых плат — например, Arduino Uno, не имеют встроенных средств для работы с USB. Поэтому, чтобы позволить таким платам взаимодействовать с компьютером через порт USB, они оснащаются отдельной микросхемой адаптера USB/TTL-Serial. Выход передачи (TX) такого адаптера подсоединен к контакту приема (RX) микроконтроллера и наоборот. Это означает, что здесь можно обойти микроконтроллер и напрямую использовать плату Arduino в качестве адаптера USB/TTL-Serial. Для этого в микроконтроллер нужно загрузить скетч, который ничего не делает:

1
2
3
void setup() {}
 
void loop() {}

Затем подсоединить требуемое последовательное устройство следующим образом  (обратите внимание: на первый взгляд может казаться, что подключение должно выполняться наоборот):

  • контакт приема внешнего устройства — к контакту RX (0) платы Arduino;
  • контакт передачи внешнего устройства — к контакту TX (1) платы Arduino.

Теперь наше устройство может обмениваться данными напрямую с адаптером USB/TTL-Serial платы Arduino, обходя микроконтроллер. Когда же снова нужно будет использовать микроконтроллер, просто отсоедините устройство и загрузите требуемый скетч.

 

 

[1] TTL, Transistor-Transistor Logic — транзисторно-транзисторная логика (ТТЛ).

[2] USB, Universal Serial Bus (protocol) — протокол универсальной последовательной шины.

[3] TTY, Teletype Unit — телетайпное устройство.

[4] CU, Сalling Unit — вызывающее устройство.

[5] GPS, Global Positioning System — система глобального позиционирования.[/vc_column_text]

USB — неисчерпаемый источник последовательных портов

Одна из примечательных особенностей микроконтроллеров — их низкая стоимость, что позволяет не особенно ограничивать себя в их числе. Например, для проекта с большим числом датчиком можно или разработать сложную программу, чтобы один микроконтроллер мог выполнять опрос всех датчиков, или же дать каждому датчику свой собственный микроконтроллер. А если информацию с этих датчиков нужно передать в персональный компьютер, поначалу может показаться, что будет легче использовать для этого один микроконтроллер — по причине ограниченного количества последовательных портов. Однако благодаря шине USB количеством доступных последовательных портов можно не озабочиваться. Если микроконтроллер оснащен портом USB, его можно подсоединить к любому разъему USB компьютера, и он будет распознаваться операционной системой компьютера как еще один последовательный порт. А количество разъемов USB компьютера можно увеличить, подключив к одному из них USB-концентратор (хаб).

Например, если к компьютеру подсоединить три модуля Arduino через USB-хаб, в операционной системе появится три новых последовательных порта. На машинах под Mac OS они будут отображаться примерно так:

/dev/cu.usbmodem1441

/dev/cu.usbmodem1461

/dev/cu.usbmodem1471

В системах POSIX, включая macOS, порты часто указываются дважды: один раз как /dev/tty.usbmodemXX и еще раз как /dev/cu.usbmodemXX. Эта особенность является пережитком эпохи телефонных модемов: порты TTY[3] служили для коммутации входящих звонков, а CU[4] — для исходящих. Для устройств USB/TTL-Serial, которые применяются в этой книге, тип используемого порта не имеет существенной важности.

На машинах под Windows эти порты будут отображаться, например, так: COM8, COM9, COM10.

Большинство современных микроконтроллерных плат оснащены встроенным модулем преобразователя USB/TTL-Serial. Для тех плат, которые не имеют встроенного преобразователя, на рынке предлагаются отдельные модули ценой порядка $15–20. Один из наиболее популярных таких преобразователей с разъемом для макетных плат, который удобно использовать для подсоединения устройств, оснащенных последовательным интерфейсом технологии TTL, выпускает компания FTDI (Future Technology Devices International), сайт которой находится по адресу www.ftdichip.com. Этот преобразователь можно прибрести в разделе макетных плат и кабелей магазинов фирм Maker SHED, SparkFun, Adafruit и многих других. Доступен он в двух версиях: 5 В и 3,3 В — любую из них можно использовать для всех проектов этой книги. Кабель-переходник USB/TTL-Serial компании FTDI показан на рис. 2.4, а распиновка его разъема TTL — на рис. 2.5.

[/vc_column][/vc_row]
Добавить комментарий