74Hc595 схема подключения – Сдвиговый регистр 74HC595

Zzzloj › Блог › Управление по одному проводу семисегментным дисплеем на сдвиговых регистрах 74HC595

Достаточно часто у любителей микроконтроллеров возникает проблема с нехваткой выводов. Обычно для расширения портов ввода/вывода используют сдвиговые регистры типа 74HC595. Но для управления ими требуется целых три вывода! А можно обойтись и ОДНИМ! Именно об этом пойдет речь далее.

Совершенно случайно ко мне в руки попала вот такая игрушка. Устройство представляет собой четырех разрядный статический семисегментный дисплей, выполненный на основе сдвиговых регистров 74HC595. Модуль ориентирован на ардуино и давно снят с продажи. Но интересна схема коммутации входов. Она выполнена с использованием двух RC цепочек на входах тактирования и управления выходной защелкой и позволяет управлять выходами сдвиговых регистров всего по одному проводу вместо трех.

Полный размер

Я бы может и прошел мимо, но данную схему впервые встретил в журнале Радио еще лет 15 назад, и тогда хотелось ее повтрить, но почему-то этого не случилось.

Схема подключения индикаторов к регистрам не вызывает вопросов. Разберемся с подключением сигналов управления. Вход тактирования 11 сдвигового регистра подключается к порту микроконтроллера напрямую. Вход данных 14 подключается к той же линии через RC-цепочку R1C1, время заряда которой составляет примерно 20-25мкС. Вход управления защелкой 12 подключен через RC-цепочку R2C2, которая заряжается примерно за 250мкС.

Полный размер

Электрическая схема модуля.

Принцип управления достаточно прост. Если на вход дисплея подать очень короткий импульс около 1мкС, то RC-цепочки не успевают зарядиться, а так как сдвиговый регистр имеет достаточно высокое быстродействие, то данные в регистр вдвинуться успевают. Таким образом, длительностью импульса можно управлять зарядом конденсаторов и определять напряжение на входе данных и защелки.

Принцип работы схемы хорошо виден на осциллограмме управляющих сигналов


Передача логической единицы производится подачей импульса длительностью примерно 25мкС и короткой паузы не более 1мкС. Импульс зарядит конденсатор на входе данных до уровня логической единицы, а короткая пауза не успеет его разрядить. Фронт следующего импульса попадет на тактовый вход и запишет единицу в регистр.

Для записи в сдвиговый регистр логического нуля необходимо наоборот сперва подать паузу длиной примерно 30мкС, чтобы разрядить конденсатор на входе данных до уровня логического нуля, если ор был заряжен в предыдущем периоде. А затем подаем короткий импульс около 1мкС, чтобы его фронт записал ноль в регистр.

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

На этом можно было бы и закончить баловство, если бы не моя привычка тестировать свои железяки. Меня насторожил тот факт, что RC цепочки имеют разницу по времени заряда всего на один порядок. Отсюда полу

www.drive2.ru

Динамический ввод и вывод на 74HC595 / Блог им. CyberCat / Сообщество EasyElectronics.ru

Сей опус я решил посвятить динамическому вводу/выводу, но не программной его составляющей, здесь этого навалом, а железу. Скучных примеров исходников выкладывать не буду. Так вот, собственно, не нарадуюсь на элементарный и всем известный регистр 74HC595. Уже давно в моих конструкциях – он единственный из присутствующей логики, помимо самого контроллера. Вдохновившись некоторыми постами типа 3D Globe V2.0, и вспомнив, что у меня завалялись светодиодные матрицы 5х7 и решил из них сделать некое табло или часы какие-нить (ну не вставляют меня уже обычные 7-ми сегментники, прошлый век! 🙂 ). Подумал, как же связать обработку вывода и микроконтроллер, используя минимум портов? Ответ нашел – использовать линейку из 595-ых, всего 3 управляющих провода +2 питание, итого 5! Вся прелесть в том, что у регистра есть фиксация параллельного вывода, а значит не нужно печалиться о строгом времени вывода и прочих дрожаний и смазываний изображения! Получилось вот что:

Кстати, на прыгающие шарики меня вдохновил Oss 🙂

Что касается вывода – все просто и понятно, но мне нужно было посадить еще 10 кнопок и, естественно, на минимум портов. Использовать аноды индикации не покатит, это уже не укладывается в 3 провода к блоку индикации. А все технические приёмы, описанные на этом сайте, какие-то уж чересчур мудрёные и неудобоваримые (использовать К155ИР13 это, простите, какой-то муветон), легче уж и вправду использовать еще один контроллер. Но мы не ищем лёгких путей! На выручку опять пришел 595! И опять 3 порта! Но на эти 3 порта можно посадить хоть 1000 кнопок! Тока наращивай регистры!


Суть в том, что пока не прошел положительный перепад на PCL(12) регистра, данные на нем будут отображаться, в независимости от того что творится на выводах SI(14) и SCL(11), а значит, что порты, управляющие этими выводами можно перевести на ввод и считывать с них состояние кнопок! Главное, перед считыванием, быстро подготовить нужную группу этик кнопок. А чтобы выходные данные регистра не мешали его программированию их нужно перевести в Z-состояние. А управлять Z-состоянием можно тем же выводом PCL, ведь он не нужен пока мы работаем с последовательным вводом данных.
Если в последовательности действий, то так:
1) Подаем низкий уровень на PCL/Z (Выводы регистра переходят в Z)
2) Переводим SI и SCL на вывод, и передаем выборку группы (лог. ноль на нужную группу)
3) Переводим SI и SCL на ввод.
4) Поднимаем PCL/Z.
5) Считываем данные с SI и SCL
6) Повторяем цикл…
Небольшое замечание – из-за того что при переводе на ввод произойдет переход с 0 на 1 (подтягивающий резистор) вывода SCL, использовать Q0 регистра нельзя, потому как произойдет сдвиг и Q0 загрузится неопределенным значением от SI (как показал опыт – всегда по разному.) Но это касается только первого регистра, в следующей секции регистров его смело можно использовать.
Вобщем, посадить на эти 3 порта можно целую клавиатуру :)

we.easyelectronics.ru

Сдвиговый регистр | Электроника для всех

Иногда требуется ОЧЕНЬ много выходных портов. Особенно если хотим сделать что нибудь на светодиодах. Гирлянду какую-нибудь навороченную. Что делать? Брать под это дело ATMega128 с ее полусотней выводов? Избыточно — для ламеров. Ставить i2с расширитель портов? Дорого. Для мажоров. Тут на помощь из вековых глубин выплывает старая добрая дискретная логика. На этот раз нас выручит грошовый сдвиговый регистр. Возьму, для примера, 74HC164 он же, для любителей совковых трешевых микросхем в неубиваемом каменном корпусе, наш КM555ИР8.

У него есть 8 выходов и четыре входа. R-сброс, С-тактовый, А1 и А2 вход. На самом деле, внутри они заведены через логический элемент 2И-НЕ и идут на D триггеры. D — это такой тип триггера, который по тактовому импульсу схватывает и отправляет на выход то, что у него на входе. Как видишь, тут они цепью стоят ,передавая бит от одного к другому и нет принципиальной разницы сколько их тут будет, восемь штук или восемь миллиардов. Но чем больше, тем дольше по этой эстафете гнать данные до конца. Поэтому мы смело можем эти регистры соединять последовательно.

Получается вот такая схема:

От МК, как видно, требуется только четыре выхода. Одним (RESET) мы сбрасываем состояние регистра. Из второго (Data) побитно вылазит байтик, а тактовый CLC обеспечивает продвижение битов по регистру. Самих регистров тут три. Они сцеплены паровозом. Когда переполняется первый, то биты из него вылазят во второй, потом в третий. Итого, 24 вывода.
Катоды диодов подключены все вместе через транзистор и как только будет слово мы подаем сигнал Ready и зажигаем всю эту ботву.

Наполнять регистр просто:
1) Поднимаем и держим RESET в 1
2) Выдаем первый (старший) бит на Data.
3) Опускаем в 0 и поднимаем в 1 тактовый выход. На восходящем фронте происходит занос в регистр и сдвиг всей цепочки на один шаг.
4) Повторить со второго пункта пока все биты не выдадим.

А для сброса достаточно уронить Reset в ноль на пару микросекунд.
Все просто 🙂

З.Ы.
Кружок на входе регистра означает, что вход инверсный. Т.е. подал ноль — сработало
Треугольник на входе показывает по какому фронту произойдет срабатывание. Запомнить просто: _/ \_ — это, типа, импульс. А треугольник, как стрелочка, указывает на нужный фронт. ->_/ \_ передний (восходящий фронт) и _/ \_<- задний (нисходящий фронт)

Ну и даташитик напоследок, а еще протеусовская модель, где можно вручную переключателем поперетыкать уровень на входе и потыкать кнопку тактового входа. Правда я там поленился на диоды питание заводить — там по квадратикам логических уровней итак все видно хорошо 🙂

easyelectronics.ru

Сдвиговые регистры 74hc595 и ARDUINO, множим выходы.

byte Reg1[8]; // массив для каждого регистра

byte Reg2[8];

 

byte num1[8] ={0,0,0,0,1,1,1,1}; //массивы которые поместим в регистры,

                                 //каждый элемент отвечает за один порт регистра

byte num2[8] ={1,0,0,0,1,0,0,0};

//Пины подключены к ST_CP входу 74HC595

int latchPin = 5; // для одного регистра

int latchPin2 = 6;  // для другого регистра

//Пин подключен к SH_CP входу 74HC595

int clockPin = 3;

//Пин подключен к DS входу 74HC595

int dataPin = 4;

 

 

 

void setup() {

  // put your setup code here, to run once:

 

   pinMode(latchPin, OUTPUT);

   pinMode(latchPin2, OUTPUT);

   pinMode(dataPin, OUTPUT);

   pinMode(clockPin, OUTPUT);

}

//процедура записи в регистр 1

void REGIDSTRI()

{

byte bitsToSend = Reg1[0]*1<<0 | Reg1[1]*1<<1 | Reg1[2]*1<<2 | Reg1[3]*1<<3 | Reg1[4]*1<<4 | Reg1[5]*1<<5 | Reg1[6]*1<<6 | Reg1[7]*1<<7 ;

//Отключаем вывод на регистре

   digitalWrite(latchPin, LOW);

  // проталкиваем байт в регистр

  shiftOut(dataPin, clockPin, MSBFIRST, bitsToSend);

    // «защелкиваем» регистр, чтобы байт появился на его выходах

  digitalWrite(latchPin, HIGH);

}

//процедура записи в регистр 2

  void REGIDSTRI2()

{

  /////////////////////////////////////////////////////////////////////////////////////////////////////////////

byte bitsToSend = Reg2[0]*1<<0 | Reg2[1]*1<<1 | Reg2[2]*1<<2 | Reg2[3]*1<<3 | Reg2[0]*1<<4 | Reg2[5]*1<<5 | Reg2[6]*1<<6 | Reg2[7]*1<<7 ;

//Отключаем вывод на регистре

   digitalWrite(latchPin2, LOW);

  // проталкиваем байт в регистр

  shiftOut(dataPin, clockPin, MSBFIRST, bitsToSend);

    // «защелкиваем» регистр, чтобы байт появился на его выходах

  digitalWrite(latchPin2, HIGH);

 

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////  

}

 

void loop() {

     memcpy( Reg1,num1,8);  // помещаем значение массива num1 в массив Reg1

     memcpy( Reg2,num2,8);  // помещаем значение массива num2 в массив Reg2

 

   REGIDSTRI (); //записываем массив Reg1 в первый регистр

   REGIDSTRI2 ();//записываем массив Reg2 во второй регистр

   delay(1000);

}

it-chainik.ru

Сдвиговый регистр 74HC595 — AVR devices

Когда необходимо подключить к контроллеру два десятка светодиодов или еще чего на помощь приходят сдвиговые регистры. Ну не тратить же драгоценные пины микроконтроллера на это дело 🙂 Для эксперимента купил сдвиговый регистр 74HC595 и в этой небольшой статье покажу как с ним работать при помощи самого крохотного контроллера Tiny13.


Посмотрим что из себя представляет эта микруха. Распиновка на рисунке ниже:

С первого взгляда кажется немного запутано, будем разбираться. Начнем с назначения выводов:

  • Q0…Q7 — выходы которыми будем управлять. Могут находится в трёх состояниях: логическая единица, логический ноль и  высокоомное Hi-Z состояние
  • GND — земля
  • Q7′ — выход предназначенный для последовательного соединения регистров.
  • MR — сброс регистра.
  • SH_CP — вход для тактовых импульсов
  • ST_CP — вход «защёлкивающий» данные
  • OE — вход переводящий выходы из HI-Z в рабочее состояние
  • DS — вход данных
  • VCC — питание 5 вольт

Для управления нам вполне достаточно всего лишь трёх  выводов а именно: SH_CPST_CP, DS.

Как работает регистр
Все не так сложно, как кажется на первый взгляд.  Когда на тактовом входе SH_CP появляется логическая единица, регистр считывает бит со входа данных DS и записывает его в самый младший разряд. При поступлении на тактовый вход следующего импульса, всё повторяется, только бит записанный ранее сдвигается на один разряд, а его место занимает вновь пришедший бит. Когда все восемь бит заполнились и приходит девятый тактовый импульс то регистр снова начинает заполнятся с младшего разряда  и всё повторятся вновь. Что бы данные появились на выходах Q0…Q7 нужно их «защёлкнуть». Для этого необходимо подать логическую единицу на вход ST_CP. Что бы мы не делали с регистром, данные на выходах не изменятся пока мы вновь не «защёлкнем» их. Отсюда кстати пошло название «регистр-защёлка». Теперь пару слов о других выводах микросхемы. Когда на входе OE лог 1 то выходы находятся в высокоомном состоянии. Когда подаем на этот вход логический 0, тогда выходы работают в нормальном режиме. MR — сбрасывает регистр устанавливая все выходы Q0…Q7 в состояние логического нуля. Для осуществления сброса нужно подать логический ноль на этот вход. После этого «защёлкнуть» данные. В нормальном состоянии на этом выводе должна находится логическая единица. Q7′ предназначен для последовательного соединения сдвиговых регистров. Можно соединить хоть десяток штук!

Программное обеспечение
Для того чтоб управлять этим регистром была написана небольшая библиотека. Вы без труда сможете использовать её в любом своем проекте. Состоит она всего навсего из одной процедуры ShiftRegOut перед вызовом которой нужно загрузить в регистр temp то что должно быть записано в сдвиговый регистр. Код неплохо прокомментирован, поэтому вопросов я думаю не будет. Если будут то прошу задавать их в комментариях. Если паять совсем лениво то можно собрать тестовую схемку в симуляторе Proteus. Файл симуляции прилагается. Если же хочется попробовать в настоящем железе то вот сама схема:

Кстати существуют регистры работающие на вход с параллельной загрузкой и последовательным выводом. Если требуется чтобы в ходе работы программы  назначение пина можно было менять, (делать входом или выходом) то применяют так называемые расширители портов. Они обычно имеют интерфейс i2c но слишком дороги и малораспространенны во всяком случае у нас. Так что сдвиговые регистры наше все =)
Ну и напоследок фото того на чем это всё проверялось и отлаживалось:

Кстати очень удобно для отладки использовать мини макетки для SOIC корпусов. Рекомендую взять на заметку =). Все вопросы складываем в комментарии.

Файл симуляции + исходник
Чисто по приколу записал видео всего этого безобразия

avrdevices.ru

Ардуино: всё о сдвиговом регистре

Ардуино: всё о сдвиговом регистре

Сдвиговый регистр — очень распространенное устройство, которое часто применяется для упрощения работы с сегментными индикаторами, с линейками и с матрицами светодиодов. Все эти устройства состоят из множества светодиодов, и если управлять ими напрямую, потребуется занять много выводов контроллера. К примеру, для подключения обычного сегментного индикатора необходимо задействовать восемь выводов. Два таких индикатора займут уже 16 ног Ардуино.

Регистр позволяет нам увеличить количество цифровых выводов микроконтроллера, и мы сможем управлять любым количеством светодиодов, реле, зуммеров и любых других цифровых устройств.

В электронике регистром называют устройство, которое может хранить небольшой объем данных для быстрого доступа к ним. Они есть внутри каждого контроллера и микропроцессора, включая и микроконтроллер Atmega328 — сердце Ардуино Уно. Как правило регистры представляют собой сборку из D-триггеров — элементарных ячеек памяти, с которыми мы уже встречались в отдельном уроке. Записывать данные в регистр можно либо последовательно, либо параллельно. Регистры первого типа называются сдвиговыми, второго типа — параллельными.

Считывать данные из регистра можно одновременно из всех ячеек. Именно это его свойство помогает нам работать с кучей светодиодов.

Вконтакте

Facebook

Twitter

Принцип работы сдвигового регистра

robotclass.ru

Больше чипов 74xx: сдвиговые регистры и декодеры

Благодаря заметке Два способа мультиплексирования светодиодов на примере микроконтроллеров AVR мы с вами знаем, что можно управлять сотней светодиодов, используя всего лишь 11 пинов микроконтроллера. Но что делать, если нужно управлять двумястами или, скажем, тысячью светодиодами? Оказывается, что изученные способы мультиплексирования могут быть улучшены, да так, что используя всего лишь три пина микроконтроллера можно управлять абсолютно любым количеством светодиодов! И в этом нам помогут следующие микросхемы.

Примечание: Если вы пропустили предыдущий пост, посвященный микросхемам 74xx, вот он — Интегральные схемы: чипы стандартной логики 74xx. Впрочем, тот пост был посвящен логическим вентилям, и для понимания представленного далее материала читать его не требуется.

SIPO сдвиговый регистр 74HC595

Сдвиговые регистры — это микросхемы, позволяющие, очень грубо говоря, добавить пинов вашему микроконтроллеру 🙂 Для добавления пинов на запись, используются SIPO сдвиговые регистры. SIPO означает «последовательный вход, параллельный выход». Если же нужно больше пинов на чтение, используются сдвиговые регистры PISO, «параллельный вход, последовательный выход». В данном разделе мы познакомимся с типичным SIPO сдвиговым регистром, 74HC595.

Какой пин 74HC595 для чего предназначен, можно узнать из даташита [PDF]:

Если коротко, то:

  • VCC, GND — это питание.
  • OE — разрешение вывода. Чтобы вывод был всегда разрешен, можно подключить этот пин напрямую к минусу.
  • SRCLR — сброс. Если не используется, то нужно подключить напрямую к плюсу.
  • SER, SRCLK — используются для передачи данных. При подаче высокого напряжения на SRCLK происходит считывание одного бита данных с пина SER.
  • RCLK — при подаче сюда высокого напряжения происходит одновременный вывод принятых данных на параллельные выходы.
  • Qa-Qh — параллельные выходы. Сюда происходит вывод последних восьми полученных бит при подаче высокого напряжения на SRCLK.
  • Qh’ — при получении очередного бита информации и смещении значений по параллельным выходам бит Qh на самом деле не отбрасывается, а поступает на этот пин. Подключив его к пину SER другого сдвигового регистра, а также соединив выходы RCLK и SRCLK обоих сдвиговых регистров, можно получить 16-разрядный сдвиговый регистр. Второй сдвиговый регистр в свою очередь можно соединить с третьим и так далее, получив сколь угодно разрядный регистр сдвига.

Надеюсь, идея ясна — мы последовательно передаем на сдвиговый регистр восемь бит информации по одному биту. Затем сдвиговый регистр параллельно выводит полученные биты на восемь пинов. Отсюда и «последовательный вход, параллельный выход».

Пример кода:

const uint8_t hc595_data  = 6; /* SER */
const uint8_t hc595_latch = 7; /* RCLK */
const uint8_t hc595_clock = 8; /* SRCLK */

/* … */

void setup()
{
  pinMode(hc595_data, OUTPUT);
  pinMode(hc595_latch, OUTPUT);
  pinMode(hc595_clock, OUTPUT);

  /* … */
}

/* … */

void loop()
{
  /* … */
  digitalWrite(hc595_latch, LOW);
  shiftOut(hc595_data, hc595_clock, MSBFIRST, hc595_out);
  digitalWrite(hc595_latch, HIGH);
  /* … */
  delay(100);
}

Нам даже не нужно писать никаких циклов. В Arduino уже предусмотрена готовая процедура shiftOut, которая делает все за нас.

В итоге три пина микроконтроллера эффективно превратились в восемь пинов. Если соединить несколько сдвиговых регистров, как это было описано выше, то можно вместо восьми пинов получить сколько угодно. При этом в микроконтроллере все так же будет задействовано только три пина.

Существует чип 74HC164, который предоставляет аналогичную функциональность, и имеет при этом 14 пинов вместо 16-и. Его даташит можно полистать здесь [PDF].

PISO сдвиговый регистр 74HC165

Типичным представителем PISO сдвиговых регистров является 74HC165.

Картинка из даташита [PDF]:

Назначение пинов:

  • VCC, GND — питание.
  • A-H — входы сдвигового регистра.
  • SH — когда на этом пине низкое напряжение, происходит считывание данных с пинов A-H.
  • CLK INH — что-то делает только при высоком напряжении на SH. Низкое напряжение означает разрешить использование часов (пин CLK). На практике можно подключить напрямую к земле.
  • CLK — когда на SH высокое напряжение и на CLK INH низкое, при подаче на CLK низкого напряжения происходит сдвиг данных.
  • Qh — выход сдвигового регистра. Одноименный выход с чертой — это инвертированный выход.
  • SER — при очередном сдвиге освободившийся бит принимает значение, поданное на этот пин. Пин может быть задействован при одновременном использовании нескольких сдвиговых регистров. Или можно просто подключить к земле.

Пример кода, считывающего состояние восьми кнопок, используя всего лишь три пина:

const uint8_t hc165_data = A5; /* QH */
const uint8_t hc165_latch = A4; /* SH */
const uint8_t hc165_clock = A3; /* CLK */

/* … */

void setup()
{
  /* … */

  pinMode(hc165_data, INPUT);
  pinMode(hc165_clock, OUTPUT);
  pinMode(hc165_latch, OUTPUT);
}

uint8_t shiftIn165(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder)
{
  uint8_t value = 0;
  uint8_t i;

  for (i = 0; i < 8; ++i)
  {
    digitalWrite(clockPin, LOW);
    if (bitOrder == LSBFIRST)
      value |= digitalRead(dataPin) << i;
    else
      value |= digitalRead(dataPin) << (7 — i);
    digitalWrite(clockPin, HIGH);
  }

  return value;
}

void loop()
{
  digitalWrite(hc165_latch, LOW);
  delayMicroseconds(5);
  digitalWrite(hc165_latch, HIGH);
  delayMicroseconds(5);

  hc595_out = shiftIn165(hc165_data, hc165_clock, MSBFIRST);

  /* … */

  delay(100);
}

Встроенная процедура shiftIn для работы с 74HC165, к сожалению, не годится, так в ней используется обратный порядок подачи сигналов LOW и HIGH на clockPin. Поэтому в приведенном коде используется собственная реализация с правильным порядком.

Декодер / демультиплексор 74HC138

В данном контексте было бы большим упущением не рассказать про демультиплексоры, так как они могут быть использованы для управления светодиодными матрицами, так же, как и сдвиговые регистры. Грубо говоря, демультиплексоры занимаются тем, что декодируют числа из бинарного представления в унарное. Типичным представителем демультиплексоров является 74HC138.

Вот иллюстрация из его даташита [PDF]:

Назначение пинов:

  • VCC, GND — питание.
  • A, B, C — три бита входа.
  • Y0-Y7 — выход. Если на вход подан ноль в бинарном представлении, на Y0 будет подано низкое напряжение, а на все остальные выходы высокое. Если подана единица в бинарном представлении, на Y1 будет низкое напряжение, а на всех остальных выходах высокое, и так далее.
  • G1, G2A, G2B — разрешение вывода. Чтобы на выходах Y0-Y7 было что-то осмысленное, на G1 должно быть подано высокое напряжение, а на G2A и G2B — низкое. Иначе на всех выходах Y0-Y7 будет высокое напряжение независимо от входов A, B и C. Пины G2A и G2B можно просто подключить к земле.

Пример кода:

const uint8_t hc138_a = 5;
const uint8_t hc138_b = 4;
const uint8_t hc138_c = 3;
const uint8_t hc138_enable = 9;

/* … */

uint8_t hc138_out = 0;

void setup()
{
  /* … */

  pinMode(hc138_a, OUTPUT);
  pinMode(hc138_b, OUTPUT);
  pinMode(hc138_c, OUTPUT);
  pinMode(hc138_enable, OUTPUT);

  /* … */
}

/* … */

void loop()
{
  /* … */

  digitalWrite(hc138_enable, LOW);
  digitalWrite(hc138_a, hc138_out & (1 << 0));
  digitalWrite(hc138_b, hc138_out & (1 << 1));
  digitalWrite(hc138_c, hc138_out & (1 << 2));
  digitalWrite(hc138_enable, HIGH);
  hc138_out = (hc138_out + 1) & B00000111;

  delay(100);
}

74HC138 может быть использован в бегущей строке. При использовании матричной схемы мультиплексирования светодиодов с его помощью можно выбирать строку светодиодной матрицы.

Существует также чип 74HC154. Он аналогичен по функциональности, но более громоздок и является четырехбитным. Его даташит можно полистать здесь [PDF].

Как несложно догадаться, если есть демультиплексоры, значит бывают и мультиплексоры. Они в каком-то смысле аналогичны PISO сдвиговым регистрам, так как позволяют увеличить количество читающих пинов микроконтроллера. В качестве примеров можно привести чипы 74HC151 и 74HC153. Их даташиты доступны, соответственно, здесь [PDF] и здесь [PDF].

Fun fact! При помощи мультиплексора можно реализовать произвольную логическую функцию, подключив его входы напрямую к питанию или земле в соответствии с таблицей истинности и используя управляющие сигналы, как входные данные.

Полная версия кода

Вы, конечно же, поняли, что приведенные выше отрывки кода являются частью одной программы. Вот ее полный исходный код:

#include <Arduino.h>

const uint8_t hc595_data  = 6; /* SER */
const uint8_t hc595_latch = 7; /* RCLK */
const uint8_t hc595_clock = 8; /* SRCLK */

const uint8_t hc138_a = 5;
const uint8_t hc138_b = 4;
const uint8_t hc138_c = 3;
const uint8_t hc138_enable = 9;

const uint8_t hc165_data = A5; /* QH */
const uint8_t hc165_latch = A4; /* SH */
const uint8_t hc165_clock = A3; /* CLK */

uint8_t hc595_out = 0;
uint8_t hc138_out = 0;

void setup()
{
  pinMode(hc595_data, OUTPUT);
  pinMode(hc595_latch, OUTPUT);
  pinMode(hc595_clock, OUTPUT);

  pinMode(hc138_a, OUTPUT);
  pinMode(hc138_b, OUTPUT);
  pinMode(hc138_c, OUTPUT);
  pinMode(hc138_enable, OUTPUT);

  pinMode(hc165_data, INPUT);
  pinMode(hc165_clock, OUTPUT);
  pinMode(hc165_latch, OUTPUT);
}

uint8_t shiftIn165(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder)
{
  uint8_t value = 0;
  uint8_t i;

  for (i = 0; i < 8; ++i)
  {
    digitalWrite(clockPin, LOW);
    if (bitOrder == LSBFIRST)
      value |= digitalRead(dataPin) << i;
    else
      value |= digitalRead(dataPin) << (7 — i);
    digitalWrite(clockPin, HIGH);
  }

  return value;
}

void loop()
{
  digitalWrite(hc165_latch, LOW);
  delayMicroseconds(5);
  digitalWrite(hc165_latch, HIGH);
  delayMicroseconds(5);

  hc595_out = shiftIn165(hc165_data, hc165_clock, MSBFIRST);

  digitalWrite(hc595_latch, LOW);
  shiftOut(hc595_data, hc595_clock, MSBFIRST, hc595_out);
  digitalWrite(hc595_latch, HIGH);

  digitalWrite(hc138_enable, LOW);
  digitalWrite(hc138_a, hc138_out & (1 << 0));
  digitalWrite(hc138_b, hc138_out & (1 << 1));
  digitalWrite(hc138_c, hc138_out & (1 << 2));
  digitalWrite(hc138_enable, HIGH);
  hc138_out = (hc138_out + 1) & B00000111;

  delay(100);
}

Фотография соответствующего прототипа на макетной плате:

Используемые чипы слева направо — микроконтроллер ATmega328P, SIPO сдвиговый регистр 74HC595, демультиплексор 74HC138, PISO сдвиговый регистр 74HC165. Состояние восьми кнопок считывается через 74HC165. Светодиоды слева, соответствующие нажатым кнопкам, не горят, а отпущенным — горят. Состояние этих светодиодов контролируется через 74HC595. На фото я зажал три правые кнопки карандашом и потому три соответствующих им светодиода не горят. Еще восемь светодиодов справа контролируются демультиплексором 74HC138. Их состояние зависит только от времени, по очереди гаснет один светодиод.

Примечание: Вас могут заинтересовать статьи Как собрать Arduino прямо на макетной плате и Собираем USB-программатор для AVR из ATmega328P и FT232.

Заключение

Еще из интересных чипов стоит упомянуть шинный формирователь 74HC244. Это штука, которая может как бы отрезать одну часть цепи от другой. Если добавить в цепь 74HC04 (логическое НЕ), то при помощи 74HC244 можно будет использовать одни и те же пины для работы с SIPO и PISO сдвиговыми регистрами, плюс один пин для переключения между ними. Итого, если микроконтроллер имеет четыре пина, он может работать с любым количеством кнопок и светодиодов. У самого маленького известного мне микроконтроллера ATtiny13 целых пять свободных пинов, что позволяет обойтись и без 74HC04. Подробности о 74HC244 ищите в даташите [PDF], там все очень просто.

Также заслуживает внимания чип 74HC4051. Эта штука позволяет соединить аналоговый канал с любым из 8 других аналогвых каналов, или разъединить их все. Мне нравится думать о 74HC4051, как о переключателе, управляемом программного. Подробности — в даташите [PDF].

В контексте увеличения числа пинов микроконтроллера стоит также упомянуть чипы MCP23017 / MCP23S17 [PDF] и специализированные чипы для управления светодиодными матрицами вроде MAX7221 [PDF]. Интересны они тем, что предлагая функциональность, аналогичную функциональности сдвиговых регистров и декодеров, могут занимать меньше места на плате. Если же вы хотите увеличить числ ШИМ-пинов, обратите внимание на микросхему TLC5940 (видеообзор, библиотека). Однако обсуждение данных микросхем уже сильно выходит за рамки данного поста. Вы без труда сможете изучить их самостоятельно в качестве домашнего задания.

Итак, теперь вы знаете все необходимое, чтобы делать при помощи светодиодов потрясающие вещи, вроде таких или даже таких. Полную версию исходников к посту вы найдете в этом репозитории на GitHub. Как обычно, буду весьма рад вашим вопросам и дополнениям.

Дополнение: Вас также могут заинтересовать посты Знакомство с компараторами на примере чипа LM339 и Изучаем работу операционного усилителя на примере NE5532.

Метки: Электроника.

eax.me

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *