Сдвиговый регистр 74hc595

Arduino.ru

Множим выходы с помощью сдвигового регистра 74HC595

Рассмотрим типичную ситуацию, когда вам нужно больше выходов (пинов), чем может предложить контроллер Arduino. В этом случае самый простой выход — использовать сдвиговый регистр. В данном примере используется 74HC595.

74HC595 — восьмиразрядный сдвиговый регистр с последовательным вводом, последовательным или параллельным выводом информации, с триггером-защелкой и тремя состояниями на выходе.

Другими словами этот регистр позволяет контролировать 8 выходов, используя всего несколько выходов на самом контроллере. При этом несколько таких регистров можно объединять последовательно для каскадирования. Другие подходящие регистры можно поискать по комбинации “595” и “596” в серийном номере. Так, например, STP16C596 может управлять 16 светодиодами одновременно без использования дополнительных резисторов.

В данной схеме используется принцип синхронизированной последовательной передачи сигнаналов. Необходимые значения сигнала (биты HIGH или LOW) передаются в регистр один за другим, при этом регистр получает синхронизирующий сигнал, который заставляет его считать сигнал с входа. Когда байт (1 байт = 8 бит) считан, значения всех 8 бит распределены по выходам. То есть передаем в регистр сигналы последовательно, на выходах регистра имеем параллельно 8 сигналов.

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

Три возможных состояния на выходе, упомянутые выше, означают, что выход регистра может иметь не только логический ноль или единицу (HIGH или LOW), но и быть в высокоомном (высокоимпедансном) состоянии — когда выход отключен от схемы. В высокоомное состояние не может быть переведен отдельный выход, а только все выходы регистра разом. Если мы говорим об управлении светодиодами, это может быть полезно в случае, когда мы хотим переключить управление ими на другой контроллер. В примере ниже это состояние никак не используется и довольно редко может быть полезно.

Распиновка входов/выходов регистра
Пины 1-7, 15Q0 ” Q7Параллельные выходы
Пин 8GNDЗемля
Пин 9Q7″Выход для последовательного соединения регистров
Пин 10MRСброс значений регистра. Сброс происходит при получение LOW
Пин 11SH_CPВход для тактовых импульсов
Пин 12ST_CPСинронизация (“защелкивание”) выходов
Пин 13OEВход для переключения состояния выходов из высокоомного в рабочее
Пин 14DSВход для последовательных данных
Пин 16VccПитание
Пример с одним регистром
  • GND (пин 8) на землю
  • Vcc (пин 16) к питанию 5В
  • OE (пин 13) на землю
  • MR (пин 10) к питанию 5В

Итак, мы запитали регистр и сделали все выходы активными. Это несколько упрощенный способ подключения, так как в момент подачи питания на схему на выходах будут случайные значения. Можно контролировать пин MR и OE непосредственно с Arduino, чтобы обнулить входы и/или подключить выходы в нужный момент. Для упрощения схемы и минимизации количества задействованных выходов Arduino мы будем использовать более простую схему, так как значения регистров и выводов будут перезаписаны, как только программы начнет работать.

Соединяем с Arduino:

  • DS (пин 14) с 11-ым цифровой выход Arduino (на схеме синий провод)
  • SH_CP (пин 11) с 12-ым цифровым выходом (желтый провод)
  • ST_CP (пин 12) c 8-ым (зеленый провод)

Далее эти выходы в тексте и коде именуются dataPin, clockPin и latchPin соответственно. Обратите внимание на конденсатор 0.1 микрофарада на latchPin, он минимизирует шум в схеме при подаче “защелкивающего” импульса.

Подключаем светодиоды к выходам регистра 74HC595, катод (короткая ножка) светодиода подключается к общей земле, а анод (длинная ножка) через ограничительный 220-ОМ резистор к выходам регистра. При использовании регистров отличных от 74HC595 следует свериться с документацией и проверить схему подключения. К некоторым регистрам светодиоды подключаются наоборот — катод к выходам.

Ниже приведен код трех программ. Первая, “Hello world”, выводит значения байта от 0 до 255. Вторая по одному включает светодиоды. Третья циклически проходит по массиву.

Пониманию кода могут помочь “временная диаграмма сигналов” регистра и “таблица логики”. Когда clockPin переглючается с LOW на HIGH, регистр считывает значения с DS пина. По мере считывания данные записываются во внутреннюю память. Когда latchPin переключается с LOW на HIGH, данные “защелкиваются”, то есть передаются на выходы регистра, включая светодиоды.

Пример использования каскада сдвиговых регистров

В этом примере подключаются два регистра, доводя количество выходов до 16, при это на Arduino по прежнему задействовано то же количество выходов.

Подключаем второй регистр к питанию и общей земле точно так же, как и первый.

Далее DS вход (пин 14) подключается к Q7′ выходу (пин 9) первого регистра (синий провод). А SH_CP (пин 11) и ST_CP (pin 12) подключаются параллельно регистру к соответствующим входам первого регистра. Желтый и зеленый провод соответственно.

К выходам второго регистра подключаем зеленые светодиоды.

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

Сдвиговый регистр – это набор последовательно соединённых триггеров (обычно их 8 штук). В отличии от стандартных регистров, сдвиговые поддерживают функцию сдвига вправо и влево. (т. е. переписывание данных с каждого предыдущего триггера на следующий по счёту).

Функционал и назначение у сдвиговых регистров довольно велик. Сегодня мы познакомим одного из них с Arduino (Отличный способ множить выходы у Arduino: занимаем 3, получаем 8).

Наверное самая популярная микросхема, представляющая собой такой регистр – это 74HC595.

– Работает на интерфейсе SPI: ноги DS, ST_CP, SH_CP – это шины управления. Соответственно: шина данных(MOSI), защёлка(SS) и тактовая линия(SCK). Подключаем на любые 3 контакта Arduino (библиотека SPI в коде не будет задействована). У меня это 12, 10, 13 выходы Arduino (стандарт).

– Ноги Q0, Q1, . Q7 – это выходы регистра (разряды). Для того, чтобы следить за состоянием каждого из них, повесим на каждый вывод по светодиоду (с последовательно соединённым резистором. Номинал от 150 до 330 Ом)

– VCC и GND – это питание. Подключаем к +5v и GND.

– выход Q7` не трогаем (предназначен для последовательного соединения таких регистров)

– MR – это сброс. Подключаем к +5v (сброс не активен).

– ну и OE притягиваем к земле (подключаем к контакту GND).

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

На BreadBoard можно разместить вот, так:

Теперь к коду:

– как говорилось ранее, библиотека SPI использоваться не будет. Есть удобная функция shiftOut().

для начала именуем наши пины (тактовая линия – clock, данные – data, защёлка – latch):

потом в void setup() обозначаем их как выходы и сразу ставим защёлке высокий уровень, чтобы регистр не принимал сигналов:

теперь давайте попробуем что-нибудь отправить на регистр:

– для начала ставим LOW на защёлку (начинаем передачу данных. Теперь регистр принимает сигналы с Arduino).

– потом отправляем данные (т. е. отправляем байт в цифровом или двоичном виде. В двоичном проще, т. к. каждый из 8 битов отвечает за свой разряд в регистре. Проще сориентироваться глазами):

Для начала отправим байт 0b10000000; (должен будет загореться первый светодиод):

– и в конце выставляем HIGH на защёлку (заканчиваем передавать данные).

В итоге весь наш код:

Теперь вгружаем в ардуину. Результат должен быть таким (зажёгся первый светодиод):

(если у вас зажёгся не первый, а последний светодиод, то в функции shiftOut поменяйте LSBFIRST на MSBFIRST и всё станет на свои места).

Итак, получилось! Предлагаю создать функцию для того, чтобы каждый раз не писать эти 3 СТРОЧКИ:

Я назову её: sendbyte;

Эта функция отправляет регистру состояние всех разрядов сразу. Это пригодится для управления семисегментом (например). Но, чтобы использовать регистр как расширитель портов, нужно управлять каждым разрядом по-отдельности (аналогично функции digitalWrite()):

– Мы можем отправлять регистру только полный байты (8 бит – 0b00000000). Если отправить не 8, а 5 бит (например: 0b00000000), то регистр будет ждать недостающие 3 бита. Значит, что когда мы хотим изменить состояние одного разряда регистра (включить его, или выключить) мы должны, по сути, послать ранее отправленный байт, с изменением на один бит.

(P. S.: Сейчас долгое и нудное объяснение (новичкам), кому не интересно, спуститесь чуть ниже :);

– Итак, сначала создаём, так называемую (мною), базу данных, в которой будет храниться состояние каждого разряда (включен(HIGH) или выключен(LOW)). тип: boolean:

Только что у нас появился массив переменных;

Каждая переменная в данном массиве обозначает свой разряд (в нулевой (по счёту) будет храниться состояние 1 разряда, второй – 3-го, и т. д.)

– Теперь напишем функцию (я назову её: sendpin). Она будет принимать 2 значения: номер разряда, и уровень, который нам надо этому разряду приписать: высокий(HIGH) или низкий(LOW).

– из-за того, что счёт начинается с нуля, нам придётся называть первый пин нулевым. Чтобы это исправить (мы будем писать как есть(первый, значит первый), а Arduino будет сама отбавлять один), Я написал:

– Затем отмечаем изменения в базе данных:

Теперь надо сформировать из 8 битов байт и отправить его на регистр.

– для начала создаём переменные:

value – тот байт, который будем отправлять. (по умолчанию его нужно сделать нулём):

add – это переменная, которая будет хранить в себе байт текущего разряда. для первого разряда это байт 1 (0b10000000);

теперь нам нужно прокрутить в базе данных все 8 переменных и сформировать байт (делать это будем с помощью цикла for():

Итак, каждый раз мы проверяем очередной разряд в базе данных. Если он должен иметь высокий уровень, то мы прибавляем к value add и переходим на следующий разряд в цепочке (как бы сдвигаемся на разряд выше (левее). Т. е., в двоичном коде всё просто: было так: 0b01000000; сдвинули единичку влево и получилось так: 0b10000000. А вот в цифровом виде всё по-другому. Сдвиг влево аналогичен умножению на 2 (а вправо, кстати, – делению на 2)). Получается примерно так:

Читайте также:  Измеритель ёмкости на микроконтроллере pic18f1320

Теперь остаётся только послать value на регистр:

В принципе, если понять, то всё очень просто.

Итак, давайте попробуем включить 2, 4, 6, и 8 разряды отдельно (4 раза напишем в цикле нашу функцию):

И кстати, в setup-e нужно очистить регистр (послать 0).

Сдвиговый регистр 74hc595 Arduino

В какой-то момент времени вы неизбежно столкнетесь с проблемой отсутствия достаточного количества контактов на вашем ардуино для удовлетворения потребностей вашего проекта или прототипа. Решение этой проблемы? Сдвиговый регистр, а точнее Arduino сдвиговый регистр 74hc595.

Каждый кто делал проекты на Ардуино, где использовал много светодиодов, понимал, что в значительной степени ограничен контактами Arduino и не может создавать огромные проекты, требующие большого количества контактов. В нашем конкретном проекте 16 светодиодов управляются всего лишь тремя контактами Arduino. Ключевым элементом является arduino сдвиговый регистр 74hc595. Каждый сдвиговый регистр 74HC595 может принимать до 8 светодиодов, а с помощью последовательных цепочек регистров можно увеличить контакты платы от условных 3-х до бесконечного числа.

Как работает регистр сдвига?

Прежде чем мы начнем подключать чип, давайте рассмотрим, как этот процесс работает.

Первое, что нужно прояснить, – это понятие «биты» для тех из вас, кто не знаком с двоичным кодом. Когда мы говорим о «битах», мы имеем в виду одно из чисел, составляющих двоичное значение. В отличие от обычных чисел, мы обычно считаем, что первый бит является самым большим. Итак, если мы берем двоичное значение 10100010, первый бит на самом деле равен 0, а восьмой бит равен 1. Следует также отметить, если это не подразумевалось, каждый бит может быть только 0 или 1.

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

Чтобы записать эти выходы через Arduino, мы должны отправить двоичное значение в регистр сдвига, и из этого числа сдвиговый регистр может определить, какие выходы использовать. Например, если мы отправили двоичное значение 10100010, контакты, выделенные зеленым цветом на изображении выше, будут активными, а выделенные красным цветом будут неактивными.

Это означает, что самый правый бит сопоставляется как QH, а левый бит сопоставляется с QA. Выход считается активным, когда бит, сопоставленный с ним, установлен на 1. Важно помнить об этом, так как иначе вам будет очень сложно узнать, какие контакты вы используете.

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

Начинаем с 8 светодиодов

Для первой части урока нам понадобятся следующие комплектующие:

  • Arduino Uno
  • Макетная плата
  • Ардуино сдвиговый регистр 74HC595
  • 8 светодиодов
  • 8 резисторов – 220 ом должно хватить
  • Провода/перемычки

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

С надписью, направленной вверх, штифты 1-8 с левой стороны сверху вниз и 16 – 9 с правой стороны сверху вниз, как показано на рисунке ниже.

Собираем схему

Для начала подключим контакты 16 (VCC) и 10 (SRCLR) к выходу 5v на Arduino и соединяем выводы 8 (GND) и 13 (OE) с выводом Gnd на Arduino. Pin 13 (OE) используется для включения выходов, так как это активный низкий контакт, который мы можем подключить непосредственно к земле.

Затем нам нужно соединить три контакта, которыми мы будем управлять сдвиговым регистром:

  • Pin 11 (SRCLK) сдвигового регистра 74HC595 на пин 11 на Arduino – это будет называться «синхронизирующим пином»,
  • Pin 12 (RCLK) сдвигового регистра на пин 12 на Arduino – это будет обозначаться как «пин защелка»,
  • Pin 14 (SER) сдвигового регистра на пин 13 на Arduino – это будет называться «пином данных»,

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

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

Чтобы уменьшить нагромождение проводов до минимума, мы поместили резисторы и светодиоды на отдельный макет, однако, вы можете воспользоваться одной макетной платой.

При размещении светодиодов убедитесь, что они подключены по порядку, так что QA подключен к первому светодиоду, а QH подключен к последнему светодиоду, так как иначе наш код не включит светодиоды в правильном порядке. Когда вы закончите, у вас должно получится что-то вроде этого:

Скетч для ардуино

Теперь мы готовы загрузить код. Подключите свой Arduino к компьютеру и загрузите на него следующий эскиз для 74hc595 Arduino:

Для начала определим в верхней части эскиза следующее:

  • Расположение пинов: синхронизатора, защелки и данных
  • Байт, который будет хранить биты, которые указывают сдвиговому регистру, какой вывод использовать
  • Переменную, которая будет отслеживать, какой светодиод мы должны включить

В методе setup мы просто инициализируем режимы пинов и переменную светодиодов.

В методе loop (цикл) мы очищаем биты в переменной leds в начале каждой итерации, так что все биты устанавливаются в 0, так как мы хотим только включать один светодиод за раз. После этого мы увеличиваем или перезапускаем текущую переменную currentLED, чтобы затем опять включать правильный светодиод.

После этих двух операций мы переходим к более важной части – смещению бит. Сначала мы начинаем с вызова метода bitSet. Мы передаем методу bitSet байт, что хранит биты, и переменную currentLED.

Этот метод позволяет нам установить отдельные биты байта, указав их положение. Например, если мы хотим вручную установить байт в 10010, мы могли бы использовать следующие вызовы, поскольку биты, которые нам нужно установить в 1, являются вторыми справа (это позиция 1, когда мы начинаем в позиции 0) и пятый справа, который находится в положении 4:

Таким образом, каждый раз, когда мы увеличиваем текущую переменную currentLED и передаем ее методу bitSet, мы каждый раз устанавливаем бит слева от предыдущего до 1 и, таким образом сообщаем сдвиговому регистру активировать вывод слева от предыдущего.

После установки бит мы записываем на контакт защелки указание сдвиговому регистру, что собираемся отправить ему данные. Как только мы это сделаем, мы вызываем метод shiftOut, который есть Arduino. Этот метод разработан специально для использования сдвиговых регистров и позволяет просто сдвигать биты за один вызов. Для этого мы передаем данные и синхронизацию в качестве первых двух параметров, затем передаем константу LSBFIRST, которая сообщает методу, что первый бит должен быть наименее значимым, а затем мы проходим через байт, содержащий биты, которые мы действительно хотим перенести в регистр сдвига.

Как только мы закончим смещение битов, мы снова обращаемся на контакт защелки (используя HIGH в этот раз), чтобы указать, что мы отправили все данные. После того, как операция записи будет завершена, загорится соответствующий светодиодный индикатор, а затем задержится на 250 миллисекунд, прежде чем всё повторится.

16 светодиодов

Теперь перейдем к более сложной схеме используем 74hc595 Arduino для 16 светодиодов.

Детали

По большому счету в данном случае количество всех комплектующих увеличиваем вдвое, кроме, конечно, Ардуино Уно:

  • Arduino UNO (x1)
  • 74HC595 сдвиговый регистр (x2)
  • Светодиоды (x16)
  • 220 ом резисторы (x16)
  • Провода/перемычки
  • Две макетные платы (одна с 400 пинами, вторая с 830 пинами)
  • Потенциометр для контроля яркости (по желанию)

Схема соединения

Схема соединения получилась уже больше, чем при 8 светодиодах и одном регистре сдвига 74HC595.

Соберите схему как на рисунке выше и подключите первый регистр сдвига следующим образом:

  • GND (контакт 8) на землю
  • Vcc (контакт 16) – 5В
  • OE (контакт 13) на землю (GND)
  • MR (контакт 10) – 5 В
  • DS (контакт 14) – пин 11 Arduino
  • SH_CP (контакт 11) на контакт Arduino 12
  • ST_CP (контакт 12) к контакту 8 Arduino

Подключите второй регистр сдвига точно так же, но подключите DS (контакт 14) к первому выходу 9 регистра. После этого соедините контакты 1, 2, 3, 4, 5, 6, 7 и 15 из обоих регистров и светодиоды. Это соединение делает все контакты всегда активными и адресными, однако при включении Arduino некоторые из светодиодов могут быть включены. Решение для этого – подключить MR (контакт 10) и OE (контакт 13) к Arduino напрямую, но таким образом вы должны пожертвовать 2 выводами ардуины.

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

Скетч для ардуино

Варианты скетчей обычно предназначены для ограниченного числа регистров сдвига, т.к. для этого нет универсальной функции/метода. Данный код ниже переработан так, чтобы вы могли использовать неограниченное количество регистров сдвига:

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

Вы также можете использовать этот код не только для светодиодов, если вам просто нужно больше контактов для вашего Arduino, используйте функцию regWrite (int pin, bool state) для записи состояния любого вывода. И нет предела, сколько сдвиговых регистров вы используете, просто измените значение numOfRegisters, а все остальное уже втоматизировано.

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 цепочки имеют разницу по времени заряда всего на один порядок. Отсюда получается, что конденсатор на входе защелки может полностью зарядиться, если подать 10 единиц подряд. А с учетом того, что уровень логической единицы для 74НС595 начинается с напряжения 3,15В, то для полного заряда конденсатора достаточно подряд подать около 6 единиц.

В схеме использованы индикаторы с общим анодом, для отключения сегментов которых на выходе регистра необходимо записать единицы. Получается, что при включении на индикаторе цифры 1 необходимо передать двоичный код 11001111, который как раз и содержит 6 единиц. Если включать на семисегментном дисплее две единицы подряд, то как раз и получим шесть импульсов, передающих логические единицы. Такая комбинация успевает зарядеть конденсатор на входе защелки. В результате чего в момент обновления дисплея наблюдается кратковременное “подмигивание”.

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

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

Проблему решил заменой резистора R2 с 33КОм на 100КОм. Время заряда RC-цепочки увеличилось в несколько раз. Индикатор стал работать лучше. Но все равно разница между временем заряда конденсаторов на входе данных и защелки было недостаточным для вывода на дисплей четырех единиц. Да и включить при такой схеме больше четырех сдвиговых регистров подряд не получится, т.к. конденсатор С2 все равно может успеть зарядиться до уровня логической единицы.

Для окончательной доработки схемы нужно добавить один а лучше два диода для ускорения разряда С2 и заряда С1. В идеале нужно использовать диоды Шоттки, они обладают более высоким быстродействием. Результат доработки показан на схеме.

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

А вот и листинг демо программы для микроконтроллера armega328. Частота процессора 16000000Гц. Данные передаются по линии PORTC.0. Писал в CodeVisionAVR. Думаю, что по комментариям все понятно.

AVR Урок 25. SPI. Подключаем сдвиговый регистр 74HC595

Урок 25

SPI. Подключаем сдвиговый регистр 74HC595

Сегодня мы продолжим работать с шиной SPI, которую мы изучили на предыдущем занятии. Вернее мы продолжим её – эту шину изучать, только занятие теперь будет практическое. Мы возьмём определённое устройсто и попробуем данным устройством поуправлять.

А в качестве устройства мы возьмём простейшую микросхему 74HC595, которая управляется именно по интерфейсу SPI и представляет собой сдвиговый регистр. Судя по технической документации на данный регистр, разработчиком его является компания Philips.

Обратим внимание на некоторые технические характеристики данного регистра сдвига.

Граничная частота тактирования не должна превышать 100 МГц, так что с нашими 8 или 16 МГц тактировой частоты контроллера мы вряд ли данную частоту превысим.

Напряжение питания микросхемы – от 2 до 6 В.

Данная микросхема существует в двух типах корпусов – обычный DIP, а также DHVQFN16, Мы будем использовать первый вариант, поэтому и посмотрим распиновку по данному варианту

У микросхемы 16 ножек. Посмотрим их назначение в таблице

Немного расшифруем данные ножки

Q0-Q7 – восемь параллельных выходов общего назначения. Данные выходы нужны для того, чтобы мы могли как-то воспользоваться пришедшими данными по SPI – подключить линейку светодиодов, либо сегменты какого-то индикатора, либо дешифратор и т.д.

VCC – напряжение питания.

GND – общий провод.

Q7′ – последовательный выход данных. Тот же самый MISO.

DS – последовательный вход данных или MOSI.

MR – это master reset. Будет изучен в процессе использования.

SH_CP – в нашем случае это будет chip select.

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

OE – задействования выхода. При отрицательном значении последовательный выход включен, при положительном – выключен.

Также ещё нам поможет до конца понять назначение ножек поможет вот такая вот блок-схемка

Самое интересное в данной схеме – то, что мы видим здесь не один регистр, а целых два. Один из них – это обычный сдвиговый регистр, в который приходят и из которого уходят наши данные по SPI. Но также есть ещё один регистр, в который эти данные попадают не автоматически, а при определённых условиях. Уже к этому регистру, называемому регистром хранения и привязан жестко параллельный 8-разрядный выход.

Поэтому перед нами теперь встаёт задача. Как же перенести наши данные из верхнего регистра в нижний. А, оказывается, для этого нам необходим квадратный импульс на ножке 12 – ST_CP. И отрицательный фронт данного импульса и “попросит” данные спуститься сверху вниз.

Следующая задача – подключить данный сдвиговый регистр 74HC595 к контроллеру ATmega8.

Так как мы не будем пользоваться последовательным выходом из нашей микросхемы, то вывод MISO контроллера мы задейстовать не будем.

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

Вот так вот всё и подключается. Выход мы включили, хотя он нам не нужен. Позже понадобится. Включается как мы помним он ножкой OE низким уровнем. Выход MR нам не нужен. Он для перезагрузки, поэтому подтянем его к питанию. Ну и соответственно SPI. Здесь также всё несложно. Подключены ножки MISO, SCK и SS. Последнюю можно было подключить с любой ножки МК, так как она аппаратно не управляется.

Теперь нам необходимо как-то написать код и заставить всё это работать.

Создадим проект с именем MYSPI595, создадим и подключим заголовочный файл main.h со следующим содержимым

#ifndef MAIN_H_

#define MAIN_H_

#define F_CPU 8000000UL

#include

#include

#include

#endif /* MAIN_H_ */

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

Ну что ж, начнём придумывать.

Соответственно, как обычно, нам сначала необходимо будет настроить ножки портов. Все ножки SPI будут у нас настроены на выход, так как MISO мы не используем, а также мы на них установим низкий логический уровень

#include “main.h”

int main ( void )

unsigned int i =0;

DDRB |= ((1 PORTB2 )|(1 PORTB3 )|(1 PORTB5 )); //ножки SPI на выход

((1 PORTB2 )|(1 PORTB3 )|(1 PORTB5 )); //низкий уровень

while (1)

Теперь настроим саму шину SPI

((1 PORTB2 )|(1 PORTB3 )|(1 PORTB5 )); //низкий уровень

SPCR = ((1 SPE )|(1 MSTR )); //Включим шину, объявим ведущим

SPDR = 0b00000000;

Делитель и умножитель мы не включаем, так как частота на микросхеме поддерживается большая. Также мы включили SPI и настроили микроконтроллер ведущим устройством.

Затем занесли в регистр данных нули.

Ну теперь попробуем эти данные передать микросхеме

while (!( SPSR & (1 SPIF ))); //подождем пока данные передадутся

То есть как только мы занесли в регистр данных значение, контроллер начнёт их пытаться передавать. После этого мы в цикле ждём того момента, когда включится бит SPIF в регистре SPSR. Как только он включится, это будет означать, что весь полный байт передался на ведомое устройство.

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

while (!( SPSR & (1 SPIF ))); //подождем пока данные передадутся

//сгенерируем отрицательный фронт для записи в STORAGE REGISTER

PORTB |= (1 PORTB2 ); //высокий уровень

(1 PORTB2 ); //низкий уровень

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

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

Читайте также:  Система доступа на rfid картах

(1 PORTB2 ); //низкий уровень

_delay_ms (2000);

SPDR = 0b11111111;

while (!( SPSR & (1 SPIF ))); //подождем пока данные передадутся

//сгенерируем отрицательный фронт для записи в STORAGE REGISTER

PORTB |= (1 PORTB2 ); //высокий уровень

(1 PORTB2 ); //низкий уровень

_delay_ms (2000);

Посмотрим теперь схему на практике, как у нас всё собрано

Всё подключено также, как мы и видели в протеусе. Вместо 8 светодиодов у нас подключена матрица светодиодов.

Попробуем собрать код и прошить наш контроллер. Сначала светодиоды находятся в потухшем состоянии и через 2 секунды они все начинают светиться. Значит всё у нас передалось.

Ну, и теперь для пущей красоты и для точного убеждения, что байты доходят правильно, не перевёртываются и не искажаются, мы напишем код в бесконечный цикл, который будет отправлять в шину SPI числа от 0 до 255, тем самым у нас на светодиодов будет иммитация инкрементирования двоичных чисел. В main() мы сначала добавим локальную переменную для счёта

unsigned int i =0;

Напишем теперь тело бесконечного цикла

for ( i =0; i i ++)

SPDR = i ;

while (!( SPSR & (1 SPIF ))); //подождем пока данные передадутся

//сгенерируем отрицательный фронт для записи в STORAGE REGISTER

PORTB |= (1 PORTB2 ); //высокий уровень

(1 PORTB2 ); //низкий уровень

_delay_ms (50);

i =0;

Соберём код, прошьём контроллер и посмотрим результат нашей работы над кодом

Всё отлично работает.

Таким образом, мы теперь потренировались с шиной SPI на практике.

Программатор и сдвиговые регистры можно приобрести здесь:

Смотреть ВИДЕОУРОК (нажмите на картинку)

11 комментариев на “ AVR Урок 25. SPI. Подключаем сдвиговый регистр 74HC595 ”

В тексте статьи указано, что “

SH_CP — в нашем случае это будет chip select.

ST_CP — это ножка управления регистром хранения, в нашем случае это будет ножка синхронизации, на которую мы будем подавать тактовые импульсы.”,

но на схеме – наоборот. Поправьте описание ножек.

Да вроде всё нормально. ST_CP – она же PORTB2. Мы этой ножкой щёлкаем каждый бит. То есть тем самым создаём иммитацию импульсов тактирования. SH_CP – она же PORTB5 у нас всегда в низком уровне. Она и есть ножка выбора (именно в нашем случае). Если мы её поднимем в высокий уровень, передача прикроется.

В уроке противоречия, согласен с shemotehnik.

Добрый день! Просто немного непонятно. Получается щёлкать бит можно любой ногой? Для данного случая sh_cp можно было просто посадить на землю?
Ножка выбора SS(у контроллера) соединена с “ST_CP — это ножка управления регистром хранения, в нашем случае это будет ножка синхронизации, на которую мы будем подавать тактовые импульсы”.
Ножка SCK(у контроллера) соединена с “SH_CP — в нашем случае это будет chip select”. Почему наоборот?
Спасибо!

У вас ошибка. Читаем даташит:
SH_CP – shift register clock input, то есть вход для синхроимпульсов сдвигового регистра
ST_CP – storage register clock input, то есть вход для синхроимпульсов регистра хранения.

Отсюда можно сделать вывод, что к SH_CP нужно подключать как раз SCK от мастера, а к ST_CP любой другой пин, который нужно будет дергать, чтобы данные попали из сдвигового регистра в регистр хранения. Как таковой CS/SS (chip select) от SPI здесь толком-то и не нужен.

И да, последний пример – отображение чисел в двоичном виде с помощью цикла от 0 до 255 работать будет неправильно. Ибо DORD бит в SPCR у вас установлен в 0, таким образом данные будут передаваться от старшего бита к младшему (MSB), т.е. старший бит в сдвиговом регистре уедет в младший и к примеру вместо 0b00000001 на выходе получите 0b10000000

Сдвиговый регистр 74HC595 и семисегментный индикатор

В ситуации когда не хватает выходов микроконтроллера, что обычно делают? Правильно – берут микроконтроллер с большим количеством выходов. А если не хватает выводов у микроконтроллера с самым большим количеством выходов, то могут поставить и второй микроконтроллер.
Но в большинстве случаев проблему можно решить более дешевыми способами например использовать сдвиговый регистр 74HC595.

Преимущества использования сдвигового регистра 74HC595:

  • не требует никакой обвязки кроме конденсатора по питанию;
  • работает через широкораспостраненный интерфейс SPI;
  • для самого простого включения достаточно двух выходов микроконтроллера;
  • возможность практически неограниченного расширения количества выходов без увеличения занятых выходов микроконтроллера;
  • частота работы до 100 МГц;
  • напряжение питания от 2 В до 6 В;
  • дешевый — стоит менее 5 центов;
  • выпускается как в планарных корпусах (74HC595D удобен для производства), так и в DIP16 (74HC595N удобен для радиолюбителей и макетирования).

Для понимания работы регистра стоит взглянуть на функциональную схему. Она состоит из:

  • 8-битного регистра сдвига,
  • 8-битного регистра хранения,
  • 8-битного выходного регистра.

Рассмотрим какие выводы есть у сдвигового регистра 74hc595.

Общего вывод и вывод питания объяснений не требуют.

  • GND — земля
  • VCC — питание 5 вольт

Входы 74HC595:

Вход переводящий выходы из высокоимпедансного состояние в рабочее состояние. При логической единице на этом входе выходы 74HC595 будут отключены от остальной части схемы. Это нужно например для того чтобы другая микросхема могла управлять этими сигналами.
Если нужно включить в рабочее состояние микросхеме подайте логический ноль на этот вход. А если в принципе не нужно переводить выходы в высокоимпедансное состояние – смело заземляйте этот вывод.

MR — сброс регистра

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

DS – вход данных

Последовательно подаваемые сюда данные будут появляются на 8-ми выходах регистра в параллельной форме.

SHCP – вход для тактовых импульсов

Когда на тактовом входе SHCP появляется логическая единица, бит находящийся на входе данных DS считывается и записывается в самый младший разряд сдвигового регистра. При поступлении на тактовый вход следующего импульса высокого уровня, в сдвиговый регистр записывается следующий бит со входа данных. Тот бит который был записан ранее сдвигается на один разряд (из Q0 в Q1) , а его место занимает вновь пришедший бит. И так далее по цепочке.

STCP – вход «защёлкивающий» данные

Что бы данные появились на выходах Q0…Q7 нужно подать логическую единицу на вход STCP. Данные поступают в параллельный регистр который сохряняет их до следующего импульса STCP.

Выходы 74HC595

  • Q0…Q7 – выходы которыми будем управлять. Могут находится в трёх состояниях: логическая единица, логический ноль и высокоимпедансное состояние
  • Q7′ – выход предназначенный для последовательного соединения регистров.

Временная диаграмма на которой показано движение логической единицы по всем выходам регистра.

Как говориться лучше один раз увидеть, чем семь раз услышать. Я сам впервые применяя регистр 74HC595 не до конца понимал его работу и чтобы понять смоделировал нужную схему в Proteus.

Вот такая схема подключения семисегментных индикаторов к микроконтроллеру ATMega48 по SPI получилась:

Это схема с динамической индикацией, то есть в каждый момент времени загорается только одна цифра счетверенного семисегментного индикатора, потом загорается следующая и так по кругу. Но так как смена происходит очень быстро, то глазу кажется, что горят все цифры.
Кроме того одновременно эта схема и опрашивает 4 кнопки S1-S4. Добавив два сдвоенных диода можно опрашивать 8 кнопок. А добавив 4 транзистора и резистора можно подключить дополнительный 4-х знаковый индикатор.
Чтобы динамическая индикация заработала в регистры нужно послать два байта: первый байт определяет, какой из 4-х индикаторов будет работать и какую кнопку будем опрашивать. А второй, какие из сегментов загорятся.

12 thoughts on “ Сдвиговый регистр 74HC595 и семисегментный индикатор ”

По моему — это тот случай, когда объяснение простого может выглядеть сложным, а не наоборот. Что может быть проще, чем два бита переслать? В данном примере, биты, пересылаемые микроконтроллером в последовательном виде — преобразуются регистрами в параллельный. Один подает на матрицу, в роли которой выступает индикатор, данные, другой — адрес. Приведен один из примеров интерфейса периферии, обслуживаемой микроконтроллером. Я бы только добавил, что счетверенный семисегментныйт индикатор, чаще всего, используют в роли часов.

В приведенной схеме динамической индикации светодиоды семисегментного индикатора должны быть на напряжение не более 4 В. В больших индикаторах часто используется последовательное включение нескольких светодиодов: например в индикаторах высотой 5см — 4 светодиода.

Поэтому стоит сделать регистру 74HC595 высоковольтный выход: подключить по MosFET на каждый выход. Затвор на выход микросхемы, исток на землю, а к стоку — «высоковольтную» нагрузку.

А действительно, часто такие схемы обслуживают таблоиды и поболее 5 см. Там может и предложенные MosFET (КМОП, полевики с изолированным затвором) будут рентабельны — цена-то у них, как правило, кусючая. В большинстве-же случаев, достаточно будет DD1, как и DD2 подсоединить к токовым ключам, а не напрямую.
Этого не сделано на приведенной схеме, так как на DD2 может падать нагрузка одновременно с семи сегментов, а на DD1 — только с одного. А экономичность схематического решения — далеко не последнее дело, в каждом, конкретном случае.

Datasheet 74HC595 и 74HCT595 от NXP.

Если не нужно каскадирование, регистр хранения и высокоимпедансное состояние на выходах то можно обойтись 74HC164N.

А зачем, если цена фактически одна? Купить сразу несколько сотен 74HC595 по 1,50 за штуку и ставить их везде и всюду, где нужны последовательно-параллельные регистры.

Мне в 74HC595 нравится именно возможность организации статической индикации, с одновременным переключением индикаторов. Так шумов меньше, чем у индикации динамической или у статической индикации без промежуточного (буферного) регистра. К тому же во втором случае имеется паразитная засветка индикатора при частой смене показаний.

А кто и как интересно опрашивает состояние кнопок на такой схеме, регистр же не контроллер он не понимает нажата кнопка или нет, его дело просто подать соответсвующие сигналы навыходных ножках, обратной же связи нет, или я чего-то не понимаю?

Тот микроконтроллер что дает сигнал на включение разрядов индикатора.
Например логическим нулем зажигаем разряд который подключен к выводу Q0 микросхемы DD2 , тогда при нажатии кнопки S1 на 9-том контакте X1 разъема появляется логический ноль, этот сигнал и считывает микроконтроллер.

А кто и как будет считывать значения с кнопок?

В этом схеме нет алгоритм для считывание состояние кнопок.
Для управление 7сег. индик. лучше включить после 595 микросхему 2003.

Применяйте микросхему TPIC6B595DWR, которая уже содержит полевики с открытым стоком на выходе.

Рейтинг
( Пока оценок нет )
Загрузка ...
Adblock
detector