Затем в линии выбора ведомого устанавливается уровень HIGH как признак того, что передача завершена.
Полученное 10-битное значение пересчитывается, как показано в следующей строке:
int reading = ((readingH & 0b00011111) << 5)
+ ((readingL & 0b11111000) >> 3);
Каждый из двух байт содержит пять бит данных из десяти. Первый байт содержит данные в пяти младших битах. Все остальные биты, кроме этих пяти, маскируются, и затем выполняется сдвиг 16-битного значения int влево на пять разрядов. Младший байт содержит остальные данные в пяти старших битах. Они также выделяются маской, сдвигаются вправо на три разряда и прибавляются к 16-битному значению int.
Для проверки откройте монитор последовательного порта. Вы должны увидеть, как в нем появляются некоторые данные. Если повернуть шток переменного сопротивления по часовой стрелке, чтобы увеличить напряжение на аналоговом входе с 0 до 5 В, вы должны увидеть картину, похожую на рис. 9.7. Первые два двоичных числа — это два байта, полученных от MCP3008, а последнее десятичное число — это аналоговое значение между 0 и 1023.
Рис. 9.7. Просмотр сообщений в двоичном виде
В заключение
Организовать взаимодействие через интерфейс SPI без применения библиотеки очень непросто. Вам придется пройти тернистый путь проб и ошибок, чтобы добиться нужного результата. Занимаясь отладкой любого кода, всегда начинайте со сбора информации и исследования принимаемых данных. Шаг за шагом вы нарисуете полную картину происходящего и затем сможете сконструировать код, помогающий достичь желаемого результата.
В следующей главе мы исследуем последний стандартный интерфейс, поддерживаемый Arduino, — последовательный порт ТТЛ. Это стандартный вид связи «точка–точка», а не шина, но тем не менее очень удобный и широко используемый механизм обмена данными.
10. Программирование последовательного интерфейса
Последовательный интерфейс вам должен быть хорошо знаком. Он используется для программирования платы Arduino, а также для взаимодействий с монитором последовательного порта, посредством которого можно организовать обмен данными между платой и компьютером. Это можно делать через адаптер, связывающий порт USB с последовательным портом на плате Arduino, или непосредственно через адаптер последовательного порта. Адаптер последовательного порта часто называют последовательным портом ТТЛ или просто последовательным портом. Аббревиатура ТТЛ означает «транзистор-транзисторная логика» — это редко используемая в настоящее время технология, основанная на 5-вольтовой логике.
Последовательный интерфейс этого вида не является шиной. Он поддерживает взаимодействия вида «точка–точка», в которые вовлечены только два устройства — обычно сама плата Arduino и периферийное устройство.
Последовательный интерфейс ТТЛ вместо I2C или SPI обычно поддерживают большие периферийные устройства или устройства, разработанные довольно давно и традиционно использующие последовательный интерфейс ТТЛ. К их числу относятся также устройства, изначально предназначенные для подключения к последовательному порту персонального компьютера. Примерами могут служить модули GPS, мультиметры с возможностью передачи данных, а также устройства чтения штрихкодов и радиометок.
Аппаратная часть последовательного интерфейса
На рис. 10.1 изображена схема последовательного интерфейса на плате Arduino Uno.
Рис. 10.1. Последовательный интерфейс на плате Arduino Uno
Микроконтроллер ATmega328 на плате Arduino Uno имеет два контакта: Rx и Tx (прием и передача соответственно). Они дополнительно выводятся на контакты D0 и D1, но, если вы решите использовать их как обычные входы/выходы, имейте в виду, что не сможете запрограммировать Arduino, пока к ним подключены внешние устройства.
Контакты Rx и Tx составляют последовательный интерфейс аппаратного универсального асинхронного приемопередатчика (УАПП) (Universal Asynchronous Receiver Transmitter, UART) в ATmega328. Этот компонент микроконтроллера отвечает за передачу байтов данных в микроконтроллер и их прием из него.
Модель Uno имеет отдельный процессор, действующий как адаптер между портом USB и последовательным портом. Помимо различий в уровнях сигналов, шина USB имеет также более сложный протокол, чем последовательный порт, поэтому за кулисами выполняется масса преобразований разного рода, чтобы создавалось ощущение, что последовательный порт микроконтроллера ATmega328 взаимодействует с компьютером напрямую.
Модель Arduino Leonardo не имеет отдельной микросхемы интерфейса USB, вместо этого в ней используется микроконтроллер ATmega, включающий два кристалла УАПП и один интерфейс USB (рис. 10.2).
Рис. 10.2. Аппаратная поддержка последовательного интерфейса на плате Arduino Leonardo
Один из приемопередатчиков УАПП обслуживает интерфейс USB, а другой соединен с контактами Rx и Tx (D0 и D1). Это позволяет подключать внешние устройства к контактам Tx и Rx и сохранить возможность программирования платы Arduino и обмена данными с монитором последовательного порта.
Другие модели Arduino имеют иное количество и схему подключения последовательных портов, как показано в табл. 10.1. Обратите внимание на то, что Due является единственной моделью Arduino, в которой последовательные порты работают с уровнями сигналов 3,3 В, а не 5 В.
Последовательный интерфейс ТТЛ способен поддерживать связь лишь по относительно коротким линиям (в пределах нескольких метров), и чем выше скорость обмена, тем короче должна быть линия. Для передачи данных на большие расстояния был разработан электрический стандарт RS232. Персональные компьютеры, выпускавшиеся до недавнего прошлого, часто снабжались последовательными портами RS232. Стандарт RS232 изменил уровни сигналов, чтобы обеспечить передачу данных на большие расстояния, чем позволяет последовательный интерфейс ТТЛ.
Таблица 10.1. Последовательные интерфейсы УАПП в разных моделях Arduino
Модель
Число последовательных портов
Подробности
Uno
1
Линия Rx подключена к контакту D0, а линия Tx — к контакту D1. Этот порт используется также интерфейсом USB
Leonardo
2
Отдельный порт для интерфейса USB. Линия Rx подключена к контакту D0, а линия Tx — к контакту D1
Mega2560
4
Интерфейс USB подключен к контактам D0 и D1. Три других порта: Serial1 — к контактам 19 (Rx) и 18 (Tx), Serial2 — к контактам 17 (Rx) и 16 (Tx), Serial3 — к контактам 15 (Rx) и 14 (Tx)
Due
4
Отдельный порт для интерфейса USB. Последовательный порт 0 использует контакты D0 (Rx) и D1 (Tx). Три других порта: Serial1 — к контактам 19 (Rx) и 18 (Tx), Serial2 — к контактам 17 (Rx) и 16 (Tx), Serial3 — к контактам 15 (Rx) и 14 (Tx)
Протокол последовательного интерфейса
Протокол последовательного интерфейса и большая часть терминологии появились еще на заре развития компьютерных сетей. Отправитель и получатель должны были договориться о скорости обмена данными. Эта скорость, измеряемая в бодах, устанавливалась на обоих концах соединения перед началом обмена. Скорость в бодах определяет частоту переходов между уровнями сигнала. Она совпадала бы с количеством бит в секунду, если бы байт данных имел стартовый бит, стоповый бит и бит четности. То есть, чтобы получить грубую оценку скорости передачи в байтах в секунду, нужно скорость в бодах разделить на 10.