Добавил:
ivanov666
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:Цифровая и микропроцессорная техника. Учебное пособие
.pdf
5.3. Интерфейс передачи данных UART
После восьмого бита следует стоп-сигнал в виде высокого уровня, и ситуация повторяется до тех пор, пока не будут переданы
все нужные байты.
Под служебными сигналами понимают предусмотренные
протоколом дополнительные меры борьбы с ошибками, которые вызываются помехами в проводах и контактах. Чем тоньше
и длиннее провода, тем чаще и сильнее случаются помехи. Если
добавить в протокол так называемый бит четности, то он будет
передаваться в цепочке данных сразу за последним битом информационного байта и перед стоповым битом (рис. 5.8).
1
0
Два стартовых
бита
Рис. 5.8. Передача символа и служебных битов
1
Передаваемый
символ
1
0
0
# #
0
четности
бит
Стартовый
Бит
Наличие или отсутствие четного бита оговаривается в протоколе заранее наряду со скоростью и прочими параметрами.
Основные параметры передачи: скорость, количество битов, паритет (четность), длина стоп-сигнала. Отсюда вытекает важное
условие для работы UART: оба устройства должны быть настроены одинаково.
Применительно к Arduino чаще всего бит четности не используется, данные байта состоят из восьми битов, а длина
стоп-сигнала равна длине одного бита.
Скорость передачи измеряется в «бодах», т. е. битах в секунду
(округленно до сотни). Желательно выбирать из заранее сформулированных стандартных значений (рис. 5.9).
Чем выше скорость, тем быстрее бегают по проводам данные, но тем больше вероятность ошибок, поэтому рекомендуется
соблюдать принцип разумной достаточности. Для большинства
случаев рекомендуется скорость 9600 бод, байт передается примерно за 1 мс. Предельно возможная скорость передачи данных
на аппаратных UART для плат Arduino – 250 000 бод, на софтовых – 115 200 бод.
121

Глава 5. Основы архитектуры микропроцессоров и микропроцессорных систем
Рис. 5.9. Стандартные значения скорости передачи
Данными устройства могут обмениваться в обе стороны, но
несмотря на теоретическую возможность полного дуплекса, реально это происходит слегка поочередно.
В среде Arduino общение с UART происходит с помощью
класса Serial. Рассмотрим некоторые функции этого класса.
Serial.begin(long); – запускает работу порта с заданной в параметре long скоростью в бодах. У Mega 4 порта, запускаются
командами c номером, например, Serial1.begin(9600); и т. д. Все
остальные команды к портам Mega тоже осуществляются с уточнением номера порта.
Serial.end(); – останавливает работу порта, если он был ранее
запущен. На практике используется редко, но бывают случаи,
когда необходимо освободить пины «0» и «1» на какое-то время.
= Serial.available(); – возвращает в виде целочисленного числа количество принятых в буфер порта байт. Если возвращает
«0», информации не поступало. Обычно используется как триггер для приема информации.
= Serial.read(); – возвращает байт из буфера приема. Следующий вызов возвращает следующий байт и т. д. Если буфер
опустел, возвращает значение байта 0xFFFF.
Serial.print(xxx); – предоставляет большое разнообразие вариантов передачи данных в порт: от байта до строки символов и
числа с плавающей точкой. Очень удобная функция для отладки
программ.
Serial.println(xxx); – отличается от Serial.print(xxx); автоматической отправкой двух служебных символов переноса строки
после информации из входящей в параметр информации. Следующее сообщение начнется с новой строки.
Serial.write(xxx); – передает двоичные данные в порт. Возвращает число переданных байтов.
= Serial.read(); – возвращает принятые двоичные данные.
122

5.3. Интерфейс передачи данных UART
Передача информации из контроллера на компьютер с ее
отображением в мониторе – важная возможность, позволяющая
наблюдать происходящее в программе, если вставить в нее соответствующие строки. Можно выводить на экран содержимое
переменных, метки прохождения точек и т. д.
Пример передачи информации в монитор порта:
void setup() {
Serial.begin(9600); // запускаем порт
}
void loop() {
Serial.print("timer: "); // пишем слово timer:
Serial.print(millis()); // выводим кол-во мил-
лисекунд с начала запуска программы
Serial.println("ms"); // подписываем их ms,
переводим строку на новую
delay(1000); // задержка 1 сек
}
После загрузки скетча запускаем встроенный в среду Arduino
монитор порта при помощи кнопки с лупой в верхнем правом
углу окна (рис. 5.10).
Рис. 5.10. Монитор порта
Две строки Serial.print() последовательно выводят на экран
текст, значение таймера millis(), третья строка Serial.println() –
123

Глава 5. Основы архитектуры микропроцессоров и микропроцессорных систем
последнюю часть текста и переводит строку. Получается бесконечная цепочка сообщений, которые можно читать с экрана.
Пример программы работы со встроенным светодиодом:
void setup() {
pinMode(13, OUTPUT);
Serial.begin(9600);
}
void loop() {
if (Serial.available() > 0) { // если
пришла команда
char incom = Serial.read(); // считыва-
ем, опознаем, реагируем
if (incom == '1') {
digitalWrite(13, HIGH);
} else if (incom == '0') {
digitalWrite(13, LOW);
}
}
}
Данный пример программы также не требует сборки схемы.
Данные будут отсылаться в обратном направлении – от компьютера к контроллеру. Данные будут командами на включение или
выключение встроенного светодиода на 13 пине Arduino.
Если набрать в строке монитора «1» и отправить ее, нажав
кнопку «Enter», то на плате включится светодиод, а если «0» –
выключится. Таким образом можно управлять программой непосредственно из монитора порта или отправлять в нее любые
данные.
5.4. ИНТЕРФЕЙС ПЕРЕДАЧИ ДАННЫХ I2C
Интерфейс I2C второй по популярности в Arduino среде после UART, чаще используется для обмена данными между контроллером, датчиками и исполнительными устройствами.
124

5.4. Интерфейс передачи данных I2C
Интерфейс I2C (рис. 5.11) отличается от UART более высокой
скоростью стабильной передачи данных и более стабильной передачей данных на высокой скорости. Кроме того, благодаря своей архитектуре позволяет подключать к одной шине, состоящей
из линии данных и линии тактового сигнала, до 127 устройств
одновременно, не используя дополнительного оборудования, не
считая двух подтягивающих резисторов.
Vdd
I2C
Ведущее
устройство 1
I2C
Ведомое
устройство 1
Рис. 5.11. Подключение устройств через интерфейс I2C
I2C
Ведомое
устройство 2
SDA
SCL
I2C
Ведущее
устройство 2
Интерфейс I2C является протоколом синхронной связи. Это
означает, что обмен данными происходит по общему для всех
связанных устройств сигналу синхронизации. Данный сигнал
генерирует только единое главное устройство – ведущее. Данное
устройство «говорит» и «дает слово» остальным устройствам, которые называют ведомыми. Все ведомые устройства имеют уникальный номер. Мастер номера не имеет.
Обращение ведущего устройства начинается с падения уровня напряжения на линии данных (SDA), что является стартовым
сигналом для ведомых устройств. Повышение уровня напряжения на линии данных при высоком тактовом сигнале является для ведомых устройств стоп-командой. Все, что происходит
между данными событиями, называют сообщением (передачей
данных). Сама передача данных происходит по линии данных,
а линия синхронизации (SCL) необходима для одновременной
работы передающего и принимающего устройств (рис 5.12).
Структура сообщения интерфейса I2C (рис. 5.13) сложнее,
чем у UART.
125

Глава 5. Основы архитектуры микропроцессоров и микропроцессорных систем
SDA
SCL
S P
СТАРТ
Передача данных
СТОП
Рис. 5.12. Передача данных от ведущего устройства к ведомому
Сообщение
START
Старт
Кадр адреса
Read/
Writ e
Bit
ACK /
NACK
Bit
Кадр
данных 1
ACK /
8 Bits 8 Bits
NACK
Bit
Кадр
данных 2
ACK /
NACK
Bit
STOP7 or 10 Bits
Стоп
Рис. 5.13. Структура сообщения интерфейса I2C
Кадр адреса в количестве 7–10 бит (в зависимости от разновидности протокола) является идентификатором конкретного
ведомого устройства, к которому обращается ведущее устройство.
Далее в сообщении присутствует бит чтения (записи), объясняющий, что надо устройству – передать данные или получить
их (чтение или запись). ACK/NACK – биты подтверждения (неподтверждения) приема информации каждого кадра. Бит подтверждения приема информации является единственным, который генерируется в линии SCL ведомым устройством.
Интерфейс I2C предназначен для передачи информации на
небольшие расстояния, обычно в пределах одного устройства. Он
занимает своего рода промежуточное положение между интерфейсами UART и SPI по скорости, надежности, расстоянию и
использованию ресурсов.
На каждой плате Arduino имеются пины, на аппаратном
уровне поддерживающие интерфейс I2C. Для UNO, Nano, Pro
Mini это пины A4 (SDA), A5 (SCL). У Меga SDA находится на
пине 20, SCL – на пине 21.
Для удобной работы с интерфейсами в среде Arduino имеется стандартная библиотека Wire, создающая одноименный класс.
Рассмотрим некоторые его функции.
126

5.5. Интерфейс передачи данных SPI
Общие функции для ведущего и ведомого устройств:
• .begin(address) – зап уск класса, подключение к шине. Если
адрес не указан, значит, устройство является ведущим, если указан, значит, это адрес ведомого устройства;
• .write( ) – передача байта или последовательности байт в
зависимости от параметров;
• .read() – возврат очередного принятого байта;
• .available() – возврат количества принятых байтов, дост у п-
ных для приема.
Функции для ведущего устройства:
• .beginTransmission(address) – начало передач и данных ведо-
мому устройству с заданным адресом;
• .endTransmission() – прекращение передачи данных ведо-
мому устройству.
Функции для ведомого устройства:
• .onReceive(foo) – в качестве параметра указывается функ-
ция, вызываемая при получении данных от ведущего устройства;
• .onRequest(foo) – в качестве параметра указывается функ-
ция, которая вызывается, когда требуется отправить данные на
ведущее устройство.
Работа протокола на ведущем и ведомом устройствах сильно
различаются. У ведущего устройства все действия совершаются
директивным образом, команда подается тогда, когда необходимо. У ведомого устройства прием и отправка осуществляются автоматически по факту обращения от ведущего устройства. Для
приема данных требуется написать функцию, реагирующую на
команды, а для отправки необходимо всегда иметь заранее готовые данные. Ведущее устройство никогда не может отправить
информацию по собственной инициативе. Если ему требуется
постоянно быть на связи с ведомым устройством, оно вынуждено
будет регулярно обращаться к соответствующему устройству для
получения новых данных.
5.5. ИНТЕРФЕЙС ПЕРЕДАЧИ ДАННЫХ SPI
Интерфейс SPI (Serial Peripheral Bus) – шина для подключения периферийных устройств. Ее главное назначение – связать
одно ведущее устройство с одним или несколькими ведомыми
устройствами. Ведущее устройство в этом интерфейсе всегда
127

Глава 5. Основы архитектуры микропроцессоров и микропроцессорных систем
одно. Оно «руководит» всем процессом и формирует тактовые
импульсы. Если ведущим устройством является микроконтроллер, то ведомыми устройствами являются периферийные устройства (датчики, дисплеи, микросхемы ЦАП и АЦП, RFID-ридеры, модули беспроводной связи и т. д.). Этот интерфейс востребован там, где требуется высокая скорость передачи данных и не
менее высокая надежность. Использование интерфейса предполагает большое количество проводов (непосредственно для передачи данных – 3 шт.).
Интерфейс имеет и другое название – 3-ware, т. е. имеет три
линии связи между устройствами:
• MOSI – Master Output Slave Input (ведущий передает, ведо-
мый принимает);
• MISO – Master Input Slave Output (ведущий принимает,
ведомый передает);
• SCLK (SCK) – Serial Clock (тактовый сигнал).
В данном протоколе есть признаки интерфейсов UART (две
независимые шины на вход и выход) и I2C (тактовый сигнал для
надежной синхронизации, так что можно уже примерно вообразить себе общий принцип работы SPI, но в нем есть и несколько
специфических решений.
Три провода – это уже достаточно много линий. Однако для
корректной работы соединения потребуется еще. Устройств к
шине можно одновременно подключить несколько, но при этом
они не обладают уникальными идентификаторами. Ведущее
устройство должно точно знать, кому оно отправляет данные и
от кого их принимает. Для этого в протокол добавлен провод SS
(Slave Select). У каждого ведомого устройства есть для этого отдельный пин, за состоянием которого он пристально наблюдает.
Падение в низкий уровень означает, что ведущее устройство обращается конкретно к данному устройству и никакому другому.
Способы подключения ведущего и ведомых устройств:
• если ведомое устройство одно, то одноименные пины со-
единяются напрямую;
• несколько ведомых устройств соединяются с ведущим
устройством параллельно шинами MISO, MOSI и SCK, а провод SS ведет к каждому из них индивидуально. Дополнительно
требуется столько пинов, сколько на шине устройств (рис. 5.14);
128

5.5. Интерфейс передачи данных SPI
SCLK
MOSI
SPI
MISO
Master
Рис. 5.14. Подключение ведомых устройств с индивидуальными SS-шинами
SS1
SS2
SS3
SCLK
MOSI
MISO
SS
SCLK
MOSI
MISO
SS
SCLK
MOSI
MISO
SS
SPI
Slave
SPI
Slave
SPI
Slave
• SS-провод один на всех, но данные передаются сквозь
устройства с одного на другое. Пока SS-провод в низком уровне,
данные распределяются по своим местам, после подъема уровня SS-провода устройства начинают работать с принятыми данными. Достоинство – от контроллера требуется меньше пинов,
недостаток – далеко не все устройства поддерживают сквозную
передачу данных (рис 5.15).
SPI
Master
SCLK
MOSI
MISO
SS
SCLK
MOSI
MISO
SS
SPI
Slave
SCLK
MOSI
MISO
SS
SCLK
MOSI
MISO
SS
Рис. 5.15. Интерфейс SPI c организацией цепочка (кольцо)
SPI
Slave
SPI
Slave
129

Глава 5. Основы архитектуры микропроцессоров и микропроцессорных систем
Протокол передачи данных по интерфейсу SPI очень прост и
имеет два режима. Они описываются всего двумя параметрами:
• CPOL – исходный уровень сигнала синхронизации, низ-
кий равен «0» или высокий равен «1»;
• CPHA – фаза синхронизации, в какой момент импульса
будет выполнена установка и считывание данных.
Важно, чтобы все устройства в сети работали на одинаковых
режимах SPI.
Преимущества SPI: максимально прост и потому максимально быстр. Скорость может достигать десятков мегагерц, что позволяет передавать большие объемы данных в потоковом режиме.
Все шины однонаправлены, это упрощает задачу преобразования
уровней. Программная реализация тоже максимально проста.
Недостатки SPI: требует большее количество проводов и пинов, которое напрямую зависит от количества устройств (в I2C
всего два провода на любое количество абонентов), при этом тот
же I2C более стандартизирован, меньше риск столкнуться с разнотипными устройствами, работающими в разных режимах.
Интерфейс SPI преимущественно предназначен для связи
главного устройства с периферией. Из этого следуют две особенности:
• подавляющее большинство устройств, предназначенных
для работы в среде Arduino, имеют собственные библиотеки, и
все общен ие с ни м и в программе пр оисходит чер ез готовые функции, а значит, программист почти не пользуется SPI напрямую;
• небольшая и простая вст роенная библиотека для SPI пред-
назначена в основном для главного устройства. Считается, что в
качестве ведомого устройства контроллер бывает крайне редко.
Для ведомого устройства проще пользоваться непосредственно
портами SPI. Сама библиотека включает десяток функций, основные из них:
– .begin(); – запускает аппаратную шину SPI на контролле-
ре, устанавливает режимы пинов и их уровни;
– .end(); – отключает шину SPI, инициализация пинов при
этом остается;
– .setBitOrder(order); – назначает порядок вывода и ввода
битов в байте, где младший бит – первый, старший бит – последний. Применяют, если светодиоды на регистре замигают в
другом порядке;
130
Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]
