shiftOut()
shiftOut() передаёт один байт побитово через цифровой вывод, сопровождая каждый бит тактовым импульсом — удобный способ работать со сдвиговыми регистрами и другой последовательной периферией.
Полная статья
Описание
shiftOut() — это функция последовательной передачи данных: она отправляет байт бит за битом через один цифровой вывод, сопровождая каждый бит тактовым импульсом на отдельном выводе. Именно так работает большинство простых периферийных устройств — сдвиговые регистры, ЦАП, светодиодные драйверы и дисплеи с последовательным интерфейсом.
Порядок передачи задаётся параметром bitOrder: MSBFIRST означает, что первым идёт старший бит (бит 7), а LSBFIRST — что передача начинается с младшего бита (бит 0). После того как очередной бит выставлен на dataPin, функция формирует тактовый импульс на clockPin: уровень поднимается с низкого до высокого и снова опускается. Принимающее устройство считывает бит по нарастающему или спадающему фронту — это зависит от его спецификации.
Важно: если устройство захватывает данные по нарастающему фронту тактового сигнала, перед вызовом shiftOut() убедитесь, что на clockPin уже установлен низкий уровень. Иначе первый тактовый импульс окажется некорректным. Для этого достаточно вызвать digitalWrite(clockPin, LOW) один раз в setup().
Это программная реализация последовательной передачи. Библиотека SPI делает похожую работу аппаратно и обычно заметно быстрее, но использует специальные выводы платы. Для невысоких скоростей, простых устройств и учебных схем shiftOut() часто удобнее: можно выбрать почти любые цифровые выводы и легче увидеть сам принцип обмена данными.
Синтаксис
shiftOut(dataPin, clockPin, bitOrder, value)
Параметры
dataPin— вывод, через который последовательно выставляются биты. Перед использованием должен быть настроен как выход. Допустимый тип:int.clockPin— вывод тактового сигнала. Также должен быть настроен как выход. Допустимый тип:int.bitOrder— порядок передачи битов:MSBFIRST(от старшего к младшему) илиLSBFIRST(от младшего к старшему). Выбор зависит от того, что ожидает принимающее устройство — смотрите его документацию.value— передаваемое значение. Допустимый тип:byte. Если нужно передать число больше 255, придётся разбить его на байты и вызвать функцию несколько раз.
Возвращаемое значение
Функция ничего не возвращает.
Пример кода
Схему подключения можно посмотреть в руководстве по управлению сдвиговым регистром 74HC595.
//**************************************************************//
// Название : shiftOutCode, Hello World //
// Автор : Carlyn Maw, Tom Igoe //
// Дата : 25 Oct, 2006 //
// Версия : 1.0 //
// Примечания : Код для использования сдвигового регистра 74HC595 //
// : счёт от 0 до 255 //
//****************************************************************
//Пин подключён к ST_CP регистра 74HC595
int latchPin = 8;
//Пин подключён к SH_CP регистра 74HC595
int clockPin = 12;
////Пин подключён к DS регистра 74HC595
int dataPin = 11;
void setup() {
//устанавливаем пины как выходы, так как они используются в основном цикле
pinMode(latchPin, OUTPUT);
pinMode(clockPin, OUTPUT);
pinMode(dataPin, OUTPUT);
}
void loop() {
//процедура счёта вверх
for (int j = 0; j < 256; j++) {
//притягиваем latchPin к земле и удерживаем LOW на всё время передачи
digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, LSBFIRST, j);
//возвращаем latch pin в HIGH, сигнализируя микросхеме, что она
//больше не должна принимать данные
digitalWrite(latchPin, HIGH);
delay(1000);
}
}
Практические замечания
- Настройка выводов обязательна. Выводы
dataPinиclockPinнужно объявить выходами через pinMode() до первого вызоваshiftOut(). Без этого поведение будет непредсказуемым. - Только один байт за раз.
shiftOut()передаёт ровно 8 бит. Чтобы отправить 16-битное значение, вызовите функцию дважды — сначала старший байт, потом младший (или наоборот, если устройство этого требует). - Функция блокирующая. Пока
shiftOut()работает, выполнение скетча приостанавливается. Для большинства задач это несущественно, но при передаче больших объёмов данных или в критичном ко времени коде стоит рассмотреть аппаратный SPI. - Проверьте полярность тактового сигнала. Одни устройства захватывают данные по нарастающему фронту, другие — по спадающему. Если данные принимаются некорректно, начните отладку именно с этого: убедитесь, что начальный уровень
clockPinсоответствует ожиданиям устройства.
// Для последовательной передачи MSBFIRST
int data = 500;
// передаём старший байт
shiftOut(dataPin, clock, MSBFIRST, (data >> 8));
// передаём младший байт
shiftOut(dataPin, clock, MSBFIRST, data);
// Или для последовательной передачи LSBFIRST
data = 500;
// передаём младший байт
shiftOut(dataPin, clock, LSBFIRST, data);
// передаём старший байт
shiftOut(dataPin, clock, LSBFIRST, (data >> 8));