16 Битный сдвиговый регистр

16 Битный сдвиговый регистр

74HC595

Из этого руководства вы узнаете, как управлять 16 светодиодами используя всего 3 линии управления. Мы осуществим это путем последовательной передачи данных в сдвиговые регистры 74HC595.

Микросхема 74HC595 содержит 8 битный регистр хранения и 8 битный сдвиговый регистр. Данные последовательно передаются в сдвиговый регистр, затем фиксируются в регистре хранения. К регистру хранения подключены 8 выходных линий. На картинке ниже показано расположение выводов микросхемы 74HC595.

Вывод 14 (DS) это вывод данных. В некоторых описаниях он обозначается как «SER».

Когда уровень на выводе 11 (SH_CP, иногда обозначается как SRCLK) переходит из низкого в высокий, значение на выводе DS сохраняется в сдвиговом регистре, при этом данные сдвигаются на один разряд, чтобы предоставить место для нового бита.

Пока на выводе 12 (ST_CP, иногда обозначается как RCLK) низкий уровень, данные записываются в регистр сдвига. Когда уровень переходит в высокий, данные из сдвигового регистра фиксируются в регистре хранения, из которого поступают на выводы Q0…Q7.

На представленной ниже временная диаграмме, показано, каким образом можно установить на выходах Q0…Q7 микросхемы значение 11000011, учитывая что изначально там было значение 00000000.

Ниже показана схема, которую мы соберем в несколько шагов.

Мы используем перфорированную макетную плату с контроллером Atmega8, которую использовали во многих наших проектах. Добавим еще 2 пустых макетных платы и подведем к ним питание.

Установим микросхему регистра сдвига и подключим к ней питание +5 В и общий провод.

Теперь проведем 3 линии управления между микроконтроллером и регистром сдвига, для чего подсоединим:

  • PC0 к DS
  • PC1 к ST_CP
  • PC2 к SH_CP

Этими линиями являются 3 синих провода на картинке ниже.

Затем подключим светодиоды и резисторы. Я использовал резисторы сопротивлением 510 Ом, но допустимы и другие номиналы.

Для демонстрации работы схемы я написал небольшую программу, которая выводит перемещающийся из стороны в сторону огонек на 8 светодиодах.

Все это конечно впечатляет, но разве я не говорил, что мы будем управлять 16 светодиодами? Чтобы сделать это, нам потребуется еще один сдвиговый регистр 74HC595, больше светодиодов, больше резисторов и больше оранжевых и голубых проводов.

Мы используем вывод Q7, чтобы соединить регистры сдвига в одну цепочку.

Модифицированная схема показана ниже.

Мы остановились на 16 светодиодах, но можно соединить в одну цепочку еще больше регистров сдвига. Эта методика конечно не ограничивается управлением светодиодами, ее можно использовать для увеличения числа портов вывода, чтобы управлять другими видами устройств.

Одно предупреждение касательно этой методики. Когда вы включаете схему, на выходах регистров наблюдаются некоторое произвольное значение. Для того чтобы записать требуемое значение, требуется меньше микросекунды, но для некоторых схем это может стать причиной проблем. В этом случае вы должны использовать выводы MR и OE, для сброса регистров хранения.

Больше чипов 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-разрядный сдвиговый регистр. Второй сдвиговый регистр в свою очередь можно соединить с третьим и так далее, получив сколь угодно разрядный регистр сдвига.
Читайте также:  Eve online heron фит для скана

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

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.

  • 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 */

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 ) ;
>

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

hc595_out = shiftIn165 ( hc165_data, hc165_clock, MSBFIRST ) ;

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

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

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

Читайте также:  Fx 6300 какую видеокарту раскроет

Вот иллюстрация из его даташита [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 ;

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

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 ;

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

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

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

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

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

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

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 ) ;
>

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 ;

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

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

Заключение

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

Читайте также:  150 Км сколько по времени на машине

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

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

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

Блог о электронике

Иногда требуется ОЧЕНЬ много выходных портов. Особенно если хотим сделать что нибудь на светодиодах. Гирлянду какую-нибудь навороченную. Что делать? Брать под это дело ATMega128 с ее полусотней выводов? Избыточно — для ламеров. Ставить i 2 с расширитель портов? Дорого. Для мажоров. Тут на помощь из вековых глубин выплывает старая добрая дискретная логика. На этот раз нас выручит грошовый сдвиговый регистр. Возьму, для примера, 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 в ноль на пару микросекунд.
Все просто 🙂

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

119 thoughts on “Сдвиговый регистр”

mc14094 получше
я управлял 3мя индикаторами по 2м проводам

Ссылка на основную публикацию
Adblock detector