Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Цифровая и микропроцессорная техника. Учебное пособие

.pdf
Скачиваний:
3
Добавлен:
08.09.2026
Размер:
2 Мб
Скачать
☆
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
Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]