Объяснение программы для Raspberry Pi
Полный код программы приведен в конце статьи, здесь же мы кратко рассмотрим его основные фрагменты.
После того, как все необходимые соединения в схеме сделаны, мы можем подать питание на Raspberry Pi и после загрузки ее операционной системы можно начать писать программу в ней на Python. Подробнее о том, как это можно сделать, можно прочитать в статье про мигание светодиода с помощью Raspberry Pi.
В программе нам первым делом необходимо подключить (импортировать) библиотеку для работы с контактами ввода/вывода. Также мы импортируем эту библиотеку RPi.GPIO под именем “IO” (то есть переименовываем ее для использования в программе), то есть далее в программе всегда, когда мы захотим обратиться к контактам ввода/вывода, мы будем использовать слово ‘IO’.
Python
import RPi.GPIO as IO
1 | importRPi.GPIO asIO |
Иногда контакты ввода/вывода (GPIO pins), которые мы собираемся использовать в программе, могут выполнять другие функции. В этом случае во время исполнения программы мы будем получать предупреждения (warnings). Следующей командой мы укажем плате Raspberry Pi на то, чтобы она игнорировала эти предупреждения и продолжала исполнение программы.
Python
IO.setwarnings(False)
1 | IO.setwarnings(False) |
Мы можем обращаться к контактам ввода/вывода (GPIO pins) платы Raspberry Pi используя либо номер контакта на плате, либо его функциональный номер. В представленной выше распиновке контактов ввода/вывода можно увидеть, к примеру, что обозначение GPIO5 соответствует контакту PIN 29. То есть в зависимости от того, какой способ обращения к контактам мы выбрали, мы можем обращаться к рассмотренному контакту либо по номеру ‘29’, либо по номеру ‘5’. В данном проекте мы выберем способ обращения к контактам по их функциональным номерам, поэтому используем следующую команду:
Python
IO.setmode (IO.BCM)
1 | IO.setmode(IO.BCM) |
Далее мы сконфигурируем контакты GPIO4, GPIO5 и GPIO6 в качестве цифровых выходов – с них будет осуществляться управление регистром сдвига.
Python
IO.setup(4,IO.OUT)
IO.setup(5,IO.OUT)
IO.setup(6,IO.OUT)
1 |
IO.setup(4,IO.OUT) IO.setup(5,IO.OUT) IO.setup(6,IO.OUT) |
Далее запишем команду цикла, который будет исполняться 8 раз.
Python
for y in range(8):
1 | foryinrange(8) |
Также в программе мы будем использовать команду «While 1:» – она будет формировать бесконечный цикл. Внутри этого цикла все команды будут исполняться непрерывно.
1Описание и назначение сдвигового регистра 74HC595
Сдвиговый регистр 74HC595 и ему подобные используются в качестве устройств преобразования последовательных данных в параллельные, а также может использоваться как «защёлка» для данных, удерживая заданное состояние.
Схема выводов («распиновка») приведена на рисунке слева.
Назначение выводов сдвигового регистра 74HC595 и внешний вид в выводном корпусе DIP-16
Назначение выводов микросхемы 74HC595 такое.
Обозначение вывода | Назначение |
---|---|
Q0…Q7 | выходы параллельных данных; |
GND | земля (0 В); |
Q7′ | выход последовательных данных; |
MR | сброс ведущего устройства (активный низкий); |
SHCP | вход тактовых импульсов сдвигового регистра; |
STCP | вход тактовых импульсов «защёлки»; |
OE | разрешение вывода (активный низкий); |
DS | вход последовательных данных; |
VCC | питание +5 В. |
Конструктивно микросхема выполняется в нескольких типах корпусов; я буду использовать микросхему в выводном корпусе DIP-16, т.к. его проще использовать с макетной платой (бредбордом).
5Временная диаграмма работы микросхемы 74HC595
Общий вид временной диаграммы – на рисунке. Голубой пунктирной линией показаны 4 линии SPI, красной пунктирной – 8 каналов параллельных данных регистра сдвига. Точка A на шкале времени – это момент передачи в регистр сдвига числа «210», B – момент записи числа «0», C – завершение текущей итерации цикла и начало новой.
Временная диаграмма работы микросхемы 74HC595
Как видно, от А до B – 10,03 миллисекунд, а от B до С – 90,12 миллисекунд, почти как мы и задали в скетче. Небольшая добавка в 0,03 и 0,12 мс – время передачи последовательных данных от Arduino, поэтому мы тут имеем не ровно 10 и 90 мс.
Рассмотрим подробнее участок A.
Обратите внимание на временной масштаб. Теперь это микросекунды, а на предыдущем были миллисекунды
То есть это сильно укрупнённый по сравнению с первой диаграммой участок.
Диаграмма передачи числа «11010010» по SPI
В первом канале сверху – длинный импульс с нулевым уровнем, которым Arduino инициализирует передачу по линии SPI — ENABLE – выбор ведомого. В это время начинают генерироваться тактовые импульсы SPI — CLOCK (см. второй сверху канал). Для передачи одного байта генерируется 8 тактовых импульсов.
Третий канал сверху – SPI — MOSI – данные, которые мы передаём от Arduino к сдвиговому регистру. Это наше число «210» в двоичном виде – «1101 0010».
После завершения передачи линия SPI — ENABLE поднимается в высокое состояние, и мы видим, что сдвиговый регистр выставил на своих 8-ми ножках значение «1101 0010». Я выделил это голубой пунктирной линией и подписал значения для наглядности.
Теперь обратим внимание на участок B. Диаграмма передачи числа «00000000» по SPI
Диаграмма передачи числа «00000000» по SPI
Опять всё начинается с выбора ведомого и генерирования 8-ми тактовых импульсов (первый и второй каналы сверху). Данные на линии SPI — MOSI теперь – «0000 0000» (3-ий сверху канал). То есть мы записываем в этот момент в регистр число «0». Но пока передача не закончена, в регистре по прежнему хранится значение «1101 0010», которое мы выставили ранее. Оно выводится на параллельные выводы Q0..Q7 (8 нижних каналов на рисунке), а также, при наличии тактовых импульсов в линии SPI — CLOCK, выдаётся в линию SPI — MISO (см. 4-ый канал сверху) c последовательного выхода регистра Q7′, что мы тут и видим.
7Каскадное подключение регистров сдвига к Arduino
Давайте подключим три регистра сдвига 74HC595 к Arduino и попробуем управлять ими по SPI.
В разделе 3 этой статьи была дана схема подключения одного регистра 74HC595 к Arduino. Схема, когда к Arduino подключены несколько ведомых устройств в каскадном режиме, отличается не сильно. Основное отличие в том, что используется один пин выбора ведомого, который активирует одновременно все подключённые устройства (пин SS Arduino подключён ко всем входам STCP), а также данные из ведущего (выход MOSI Arduino) передаются первому в цепочке ведомому 74HC595 на вход последовательных данных DS, тот в свою очередь из последовательного порта Q7′ передаёт данные следующему ведомому на последовательный вход DS, и так далее. Последний ведомый из своего порта Q7′ передаёт данные ведущему в линию MISO, но в нашем случае это не обязательно. Остальные выводы сдвиговых регистров подключены так же, как на предыдущей схеме. У Arduino же используются те же 4 стандартных пина SPI, что и при подключении к единственному регистру сдвига.
Соберём в соответствии с этим нашу схему. У меня получилось как-то так:
Каскадное подключение трёх сдвиговых регистров к Arduino – вид со стороны параллельных выходов 74HC595 Каскадное подключение трёх сдвиговых регистров к Arduino – вид со стороны пинов управления 74HC595
Теперь напишем скетч для «бегущей волны», но теперь она будет немного длиннее. В моём случае – из 19-ти светодиодов, каждый из которых будет представлять один из разрядов параллельных выходов (на все 24 не хватило места на монтажке).
Скетч «бегущей волны» со сдвиговым регистром (разворачивается)
#include <SPI.h> void setup() { pinMode(PIN_SPI_SS, OUTPUT); SPI.begin(); Serial.begin(9600); } void loop() { for (int i=0; i<20; i++) { //вообще, тут нужно писать i<25, т.к. всего параллельных выходов у трёх регистров 24 unsigned long num = (long)1<<i; // "гоним" горящий огонёк по разрядам, сдвигая единицу на 1 разряд влево каждую итерацию /* * 19 (или 24) разрядов числа поместятся только в беззнаковый long * unsigned long может хранить до 32-х разрядов. * Т.к. у нас три сдвиговых регистра или 3*8=24 бит, то используем этот тип данных */ /* * Реализация SPI в Arduino такова, что можно передавать числа либо байтами, либо словами по 2 байта. * Поэтому делим наше число на байты, их получается 3, как и регистров сдвига: */ byte a = (byte)num; //младшие 8 бит числа byte b = (byte)(num>>8);//средние 8 бит числа byte c = (byte)(num>>16); //старшие 8 бит числа digitalWrite(PIN_SPI_SS, LOW); // начинаем передачу по SPI SPI.transfer(c); //передаём старший байт числа SPI.transfer(b); //передаём средний байт числа SPI.transfer(a); //передаём младший байт числа digitalWrite(PIN_SPI_SS, HIGH); // завершаем передачу по SPI // Контрольный вывод в COM-порт: Serial.print((String)i + ": "); Serial.print(num, HEX); Serial.print("="); Serial.print(c, HEX); Serial.print(","); Serial.print(b, HEX); Serial.print(","); Serial.println(a, HEX); delay(100); // задержимся немного } }
Обратите внимание, мы обращались к параллельным выходам 3-х сдвиговых регистров как к большому 24-разрядному числу. Но что делать, если вы подключили к Arduino большее количество 74HC595? Такими большими числами Arduino, конечно же, оперировать не умеет
В таком случае придётся работать с байтами. То есть передавать в каждый регистр своё 8-разрядное значение.
А вот так это выглядит в действии:
Каскадное подключение трёх сдвиговых регистров к Arduino в действии
На видео в конце статьи результат наглядно показан в динамике. К каждому из трёх сдвиговых регистров подключены светодиоды своего цвета – красные, зелёные и синие, и видно, как наше число «перескакивает» с регистра в регистр.
Таким образом, мы детально изучили вопрос информационного обмена между ведущим устройством, в роли которого выступил Arduino, и сдвиговым регистром 74HC595. Научились подключать сдвиговый регистр, записывать в него данные и считывать из него данные.
Как работает регистр сдвига?
Прежде чем мы начнем подключать чип, давайте рассмотрим, как этот процесс работает.
Первое, что нужно прояснить, — это понятие «биты» для тех из вас, кто не знаком с двоичным кодом. Когда мы говорим о «битах», мы имеем в виду одно из чисел, составляющих двоичное значение. В отличие от обычных чисел, мы обычно считаем, что первый бит является самым большим. Итак, если мы берем двоичное значение 10100010, первый бит на самом деле равен 0, а восьмой бит равен 1. Следует также отметить, если это не подразумевалось, каждый бит может быть только 0 или 1.
Чип содержит восемь контактов, которые мы можем использовать для вывода, каждый из которых связан с битом в регистре. В случае сдвигового регистра 74HC595 мы рассматриваем их от QA до QH.
Чтобы записать эти выходы через Arduino, мы должны отправить двоичное значение в регистр сдвига, и из этого числа сдвиговый регистр может определить, какие выходы использовать. Например, если мы отправили двоичное значение 10100010, контакты, выделенные зеленым цветом на изображении выше, будут активными, а выделенные красным цветом будут неактивными.
Это означает, что самый правый бит сопоставляется как QH, а левый бит сопоставляется с QA. Выход считается активным, когда бит, сопоставленный с ним, установлен на 1
Важно помнить об этом, так как иначе вам будет очень сложно узнать, какие контакты вы используете
Теперь, когда у нас есть основное понимание того, как мы используем смещение битов, чтобы указать, какие контакты использовать, мы можем начать подключать его к нашему Arduino.
Скетч для arduino, который считывает данные с регистра 74HC165
В завершение прикладываю код, для считывания сигналов с регистра. Скетч с подробными комментариями, описывать что-то еще нет смысла, поэтому приведу просто листинг:
#define NUMBER_OF_SHIFT_CHIPS 1 // количество регистров #define DATA_WIDTH NUMBER_OF_SHIFT_CHIPS * 8 // количество входов #define PULSE_WIDTH_USEC 5 // задержка при считывании данных // для хранения считаных байт // если регистров больше двух, то int меняется на long #define BYTES_VAL_T unsigned int // пины для подключения регистра int ploadPin = 8; int clockEnablePin = 9; int dataPin = 11; int clockPin = 12; BYTES_VAL_T pinValues; // текущее значение пинов BYTES_VAL_T oldPinValues; // предыдущее значение пинов // функция для считывания пинов BYTES_VAL_T read_shift_regs() { long bitVal; BYTES_VAL_T bytesVal = 0; // опрашиваем регистр о состоянии пинов digitalWrite(clockEnablePin, HIGH); digitalWrite(ploadPin, LOW); delayMicroseconds(PULSE_WIDTH_USEC); digitalWrite(ploadPin, HIGH); digitalWrite(clockEnablePin, LOW); // считываем полученные данные о пинах for(int i = 0; i < DATA_WIDTH; i++){ bitVal = digitalRead(dataPin); bytesVal |= (bitVal << ((DATA_WIDTH-1) - i)); digitalWrite(clockPin, HIGH); delayMicroseconds(PULSE_WIDTH_USEC); digitalWrite(clockPin, LOW); } // возвращяем результат опроса регистра return(bytesVal); } // функция для вывода состояния пинов void display_pin_values(){ // перебор всех пинов for(int i = 0; i < DATA_WIDTH; i++){ Serial.print(" Button-"); Serial.print(i); Serial.print(": "); if((pinValues >> i) & 1){ Serial.print("ON"); }else{ Serial.print("OFF"); } Serial.println(); } Serial.println(); } void setup(){ // для вывода данных в монитор порта Serial.begin(9600); // установка режима работа пинов pinMode(ploadPin, OUTPUT); pinMode(clockEnablePin, OUTPUT); pinMode(clockPin, OUTPUT); pinMode(dataPin, INPUT); digitalWrite(clockPin, LOW); digitalWrite(ploadPin, HIGH); // считываем значения с пинов pinValues = read_shift_regs(); // выводим результат display_pin_values(); // сохраняем текущее значение oldPinValues = pinValues; } void loop(){ // считываем значения с пинов pinValues = read_shift_regs(); // если значения изменились, то выводим их if(pinValues != oldPinValues){ // выводим результат в монитор порта display_pin_values(); // сохраняем текущее значение oldPinValues = pinValues; } delay(50); }
Входы 74HC595
OE
Вход переводящий выходы из высокоимпедансного состояние в рабочее состояние. При логической единице на этом входе выходы 74HC595 будут отключены от остальной части схемы. Это нужно например для того чтобы другая микросхема могла управлять этими сигналами.
Если нужно включить в рабочее состояние микросхеме подайте логический ноль на этот вход. А если в принципе не нужно переводить выходы в высокоимпедансное состояние – смело заземляйте этот вывод.
MR — сброс регистра
Переводить все выходы в состояние логического нуля. Чтобы сбросить регистр нужно подать логический ноль на этот вход и подать положительный импульс на вход STCP.
Подключаем этот выход через резистор к питанию микросхемы и при необходимости замыкаем на землю.
DS – вход данных
Последовательно подаваемые сюда данные будут появляются на 8-ми выходах регистра в параллельной форме.
SHCP – вход для тактовых импульсов
Когда на тактовом входе SHCP появляется логическая единица, бит находящийся на входе данных DS считывается и записывается в самый младший разряд сдвигового регистра. При поступлении на тактовый вход следующего импульса высокого уровня, в сдвиговый регистр записывается следующий бит со входа данных. Тот бит который был записан ранее сдвигается на один разряд (из Q0 в Q1) , а его место занимает вновь пришедший бит. И так далее по цепочке.
STCP – вход «защёлкивающий» данные
Что бы данные появились на выходах Q0…Q7 нужно подать логическую единицу на вход STCP. Данные поступают в параллельный регистр который сохряняет их до следующего импульса STCP.
Применение регистров сдвига 74HC595 или как управлять всем сразу используя всего 3 ноги МК.
595-ый – штука широко используемая когда не хватает портов вывода микроконтроллера. Для управления регистром требуется минимум два вывода контроллера (а лучше три), а выходов получаем теоретически сколько угодно (у меня максимум было 48), о чем дальше и пойдет речь.
В самом конце опишу опыт защиты от помех, например когда блок с регистрами подключен шлейфом к контроллеру, а ведь CMOS-входы, это не старый-добрый-“теплый” TTL, тут токи почти нулевые. А еще не вредно при таких подключениях предусмотреть и ситуацию, когда соединительный шлейф неожиданно сгрызли гризли, а порты управляют ядерным арсеналом.
Ну и до кучи напишу какими командами в Atmel контроллерах (ATMEGA, ATTINY) удобно работать с портами при программировании на C (всякие битовые операторы, хитрые #define для повышения читаемости кода и пр.). Вроде как такой гайд для совсем начинающих. А не начинающим лучше сразу на второй пост про помехи…
Железо:
Далее составляем принципиальную схему. Для этого открываем datasheet на светодиодный дисплей. Из всех «многа букафф» ценность представляют несколько таблиц и рисунков. Это:1) электрооптические характеристики:
Из которых следует, что наш дисплей действительно имеет общий катод и зеленый цвет свечения2)Назначение и нумерация выводов:
Из первого рисунка узнаем про нумерацию выводов, расположение сегментов и разрядов на индикаторе (например, что первый разряд (разряд десятков) имеет обозначение D1, а разряд единиц D2. Из таблицы узнаем, что вывод катода второго разряда – это вывод 13 на индикаторе, а анодам сегментов a, b, c, d, e, f, g соответствуют выводы 11, 10, 8, 6, 5, 12, 7. Вывод первого катода – 14. Но анодов для него всего 2: это сегменты b и c (15 и 3 выводы соответственно). Это значит, что на первом разряде можно засветить только цифру 1
Остальные выводы неподключенные (это немаловажно, т.к. позже я через них буду проводить дорожки, не боясь что-либо закоротить).3)И напоследок:
Убеждаемся, что ток 1 сегмента должен быть 20mA (это стандартная величина для подобных дисплеев и обычных светодиодов
На основе этой величины подбираем сопротивления, для ограничения тока.Далее составляем принципиальную схему:
Кроме светодиодного дисплея и микросхемы сдвигового регистра, которые я описал ранее, в схеме присутствуют 9 резисторов для ограничения тока до 20мА на каждый сегмент. Микросхему я установил на панельку. Также используются два разъема (один 9ми штырьковый для подключения платы напрямую к Arduino при вытянутой с панельки микросхеме и один 5ти штырьковый для подключения через микросхему сдвигового регистра.Также из-за особенности дисплея выводить в первом разряде только единицу и чтобы не использовать вторую микросхему 74HC595 я вместо «точки» подключил сегменты «b» и «c» первого разряда дисплея. Теперь при появлении на выходе Q7 сигнала высокого уровня будет зажигаться в разряде десятков цифра «1».Номера выводов дисплея я в схеме не указывал, т.к. для каждой модели дисплея они разные и брать их надо с даташита.Чтобы легче было собирать — по-быстрому в sprint layout выбрал шаг сетки 2.54мм и набросал плату.
Скачать ее можно тут.Вот как выглядит готовая плата:
К Arduino она подключается следующим образом:
Использование сдвиговых регистров в устройствах индикации.
Одной из проблем, возникающих при разработке микроконтроллерных устройств часто становится необходимость экономии линий портов ввода/вывода. Многие периферийные устройства, которые могут работать в связке с процессором, требуют для передачи информации большого количества соединительных проводников. Актуальность этой задачи не снизилась даже с появлением процессоров с большим количеством выводов, так как одновременно усложнились и периферийные устройства. Для устройств индикации, одним из вариантов снижения количества требуемых линий может стать использование регистров сдвига (Shift register).
Регистр сдвига представляет собой цепочку из нескольких, последовательно соединенных D-триггеров. На первый триггер подключается информационный выход микроконтроллера. С каждым импульсом тактового сигнала, передаваемого по отдельной линии, уровень на входе каждого из триггеров записывается на выход. В итоге происходит сдвиг сигнала от начала к концу цепочки. Если использовать подключить выходные линии после каждого из триггеров, то сдвиговый регистр будет представлять собой последовательно-параллельный преобразователь. Это значит, что для организации каких-либо индикаторов, будет минимально необходимо использовать только два вывода микроконтроллера.
В настоящее время производители предлагают большое количество моделей регистров сдвига, с различными функциональными особенностями. Далее будут рассматриваться только микросхемы с последовательным входом и параллельным выходом. Также для описываемых целей можно использовать некоторые универсальные модели регистров.
2Краткое описание интерфейса SPI
Коротко напомню о последовательном интерфейсе SPI, который мы будем использовать для передачи данных в сдвиговый регистр.
SPI – это четырёхпроводный двунаправленный последовательный интерфейс, в котором принимают участие ведущее и ведомое устройства. Ведущим в нашем случае будет являться Arduino, ведомым – регистр 74HC595.
Среда разработки для Arduino имеет встроенную библиотеку работы по интерфейсу SPI. При её применении используются цифровые выводы с 10 по 13 на платах Arduino Uno и Arduino Nano; также они продублированы и выведены на отдельный разъём ICSP:
Выводы Arduino, отведённые под SPI
Обозначение вывода | Назначение |
---|---|
SCLK | вывод тактовых импульсов SPI; |
MOSI | данные от ведущего – к ведомому; |
MISO | данные от ведомого к ведущему; |
SS | выбор ведомого. |
6Подключение нескольких регистров сдвига к Arduino
Если подключить несколько сдвиговых регистров таким образом, чтобы линии CLOCK (SCLK на рисунке ниже), MOSI и MISO у них были общие, а ENABLE (SS на рисунке) каждой микросхемы подключались к разным цифровым выводам Arduino, то можно независимо обращаться к каждому из сдвиговых регистров, активизируя низким уровнем соответствующий из них, и записывать в регистры данные и считывать из них данные. Такое подключение называется независимым.
Независимый и каскадный типы подключений по интерфейсу SPI
Независимое подключение ведомых SPI устройств (например, регистров 74HC595) к ведущему (например, Arduino) изображено на левой части рисунка. Думаю, это уже достаточно просто для нас, так как оно почти ничем не отличается от подключения одного сдвигового регистра. Поэтому давайте рассмотрим другой тип подключения – каскадный.
Выходы 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, которая уже содержит полевики с открытым стоком на выходе.
D-триггер
Кратко затронем самые основы. Глобально, электронику можно разделить на два раздела: аналоговый и цифровой. Принципиальная особенность второго заключается в том, что сигналы задаются дискретными уровнями напряжения. Притом дискретных уровня всего два. Таким образом, вместо того, чтобы записывать напряжение в вольтах, достаточно просто называть один из двух дискретных уровней. Так и появляются названия «ноль» и «единица». В действительности, они определяют некоторые уровни напряжения, которые могут быть какими угодно. Хотя, в большинстве случаев, «ноль» обозначает уровень 0 Вольт, а «единица» уровень 5 В, 3.3 В, 1.8 В, 1.5 В и т.д. Таким образом, фраза «на входе ноль, на выходе единица» обозначает: «на входе напряжение, соответствующее уровню ноль, на выходе напряжение, соответствующее уровню единица».
Двигаемся далее. Теперь у нас есть цифровой сигнал, что же интересного можно с ним сделать? Подать на D-триггер и посмотреть, что будет! Но сначала дадим пару определений.
На электрической схеме устройства D-триггер выглядит ровно так же, как на рисунке ниже. Такой вид триггера обязательно имеет три вывода: D (вход), C (вход синхронизации, вход тактирования, тактовый вход, clk, clock) и Q (выход). Помимо них могут иметься еще: инвертированный выход, входы сброса и установки значения на выходе, вход разрешения работы. Однако, суть работы заключается именно во взаимодействии трех обязательных выводов, поэтому именно их мы и рассмотрим.
рис. 1 — условное графическое обозначение D-триггера
Принцип работы D-триггера следующий: при подаче тактового сигнала на вход C, состояние на выходе становится равным состоянию на входе. Т. е. если в какой-то момент времени на входе был «ноль», а на выходе «единица», то в момент подачи тактового сигнала выход примет состояние входа и станет «нулём».
Начальное состояние |
Состояние после подачи тактового импульса |
||
Вход (D) |
Выход (Q) |
Вход (D) |
Выход (Q) |
1 |
|||
1 |
1 |
1 |
|
1 |
1 |
1 |
1 |
Отдельно стоит обсудить фразу «подача тактового сигнала». Дело в том, что срабатывание триггера (перенос значения от входа к выходу) может происходить по разным событиям. Например, когда на тактовом входе установлена логическая единица или логический ноль. Или по фронту импульса на тактовом входе, т.е. в момент перехода нуля в единицу или единицы в ноль. То, каким образом срабатывает триггер, зависит от его конструкции и обозначается на схеме специальными символами. На приведенном рисунке изображен триггер, срабатывающий по нарастающему фронту.
Заметим, что сигнал на выходе никак не меняется без подачи тактового сигнала. Это позволяет использовать D-триггер как буфер. Мы подаем тактовый сигнал, триггер считывает состояние на входе и передает его на выход. После этого мы можем хранить считанное значение в триггере, сколько нам нужно, даже когда значение на входе уже стало другим. На этом заканчивается краткий обзор принципов работы D-триггера, и мы переходим к регистрам сдвига.