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

Arduino.ru

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

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

Другими словами этот регистр позволяет контролировать 8 выходов, используя всего несколько выходов на самом контроллере.

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

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

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

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

Когда байт (1 байт = 8 бит) считан, значения всех 8 бит распределены по выходам. То есть передаем в регистр сигналы последовательно, на выходах регистра имеем параллельно 8 сигналов.

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

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

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

В примере ниже это состояние никак не используется и довольно редко может быть полезно.

Распиновка входов/выходов регистра

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

Пример с одним регистром

Подключим:

  • 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, данные “защелкиваются”, то есть передаются на выходы регистра, включая светодиоды.

 Код примера 1.1

//**************************************************************//
// Name : shiftOutCode, Hello World // Author : Carlyn Maw,Tom Igoe, David A. Mellis // Date : 25 Oct, 2006 // Modified: 23 Mar 2010 // Version : 2.0 // Notes : Программа использует один сдвиговый регистр 74HC595 // : для вывода значений от 0 до 255 //**************************************************************** //Пин подключен к ST_CP входу 74HC595
int latchPin = 8;
//Пин подключен к SH_CP входу 74HC595
int clockPin = 12;
//Пин подключен к DS входу 74HC595
int dataPin = 11; void setup() { //устанавливаем режим OUTPUT pinMode(latchPin, OUTPUT); pinMode(clockPin, OUTPUT); pinMode(dataPin, OUTPUT);
} void loop() { // отсчитываем от 0 до 255 и отображаем значение на светодиоде for (int numberToDisplay = 0; numberToDisplay < 256; numberToDisplay++) { // устанавливаем синхронизацию "защелки" на LOW digitalWrite(latchPin, LOW); // передаем последовательно на dataPin shiftOut(dataPin, clockPin, MSBFIRST, numberToDisplay); //"защелкиваем" регистр, тем самым устанавливая значения на выходах digitalWrite(latchPin, HIGH); // пауза перед следующей итерацией delay(500); } }

Код примера 1.2

/* Shift Register Example for 74HC595 shift register Created 22 May 2009 Created 23 Mar 2010 by Tom Igoe */ //Пин подключен к ST_CP входу 74HC595
int latchPin = 8;
//Пин подключен к SH_CP входу 74HC595
int clockPin = 12;
//Пин подключен к DS входу 74HC595
int dataPin = 11; void setup() { //устанавливаем режим OUTPUT pinMode(latchPin, OUTPUT); pinMode(dataPin, OUTPUT); pinMode(clockPin, OUTPUT); Serial.begin(9600); Serial.println(“reset”);
} void loop() { if (Serial.available() > 0) { // Символы от '0' до '9' // представлены в ASCII таблице значения от 48 до 57. int bitToSet = Serial.read() – 48; // Записываем HIGH в позицию соответствующую bitToSet registerWrite(bitToSet, HIGH); }
} // Этот метот записывает байт в регистр
void registerWrite(int whichPin, int whichState) {
// инициализируем и обнуляем байт byte bitsToSend = 0; //Отключаем вывод на регистре digitalWrite(latchPin, LOW); // устанавливаем HIGH в соответствующем бите bitWrite(bitsToSend, whichPin, whichState); // проталкиваем байт в регистр shiftOut(dataPin, clockPin, MSBFIRST, bitsToSend); // “защелкиваем” регистр, чтобы байт появился на его выходах digitalWrite(latchPin, HIGH);
}

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

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

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

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

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

Схема подключения

Код примера 2.1

//**************************************************************//
// Name : shiftOutCode, Hello World // Author : Carlyn Maw,Tom Igoe, David A. Mellis // Date : 25 Oct, 2006 // Modified: 21 Mar 2010 // Modified: 19 Feb 2011 // Version : 2.0 // Notes : Программа использует два сдвиговых регистра 74HC595 // : для вывода значений от 0 до 255 //**************************************************************** //Пин подключен к ST_CP входу 74HC595
int latchPin = 8;
//Пин подключен к SH_CP входу 74HC595
int clockPin = 12;
//Пин подключен к DS входу 74HC595
int dataPin = 11; void setup() { //устанавливаем режим OUTPUT pinMode(latchPin, OUTPUT); pinMode(clockPin, OUTPUT); pinMode(dataPin, OUTPUT);
} void loop() { // отсчитываем от 0 до 255 и отображаем значение на светодиоде for (int numberToDisplay = 0; numberToDisplay < 256; numberToDisplay++) { // устанавливаем синхронизацию "защелки" на LOW digitalWrite(latchPin, LOW); // передаем отсчет для вывода на зеленые светодиоды shiftOut(dataPin, clockPin, MSBFIRST, numberToDisplay); // передаем обратный отсчет для вывода на красные светодиоды shiftOut(dataPin, clockPin, MSBFIRST, 255-numberToDisplay); //"защелкиваем" регистр, тем самым устанавливая значения на выходах digitalWrite(latchPin, HIGH); // пауза перед следующей итерацией delay(500); } }

Код примера 2.2:

/* Программа поочередно включается все светодиоды, подключенные к двум
сдвиговым регистрам 74HC595 .Created 22 May 2009 Modified 23 Mar 2010 by Tom Igoe */ //Пин подключен к ST_CP входу 74HC595
const int latchPin = 8;
//Пин подключен к SH_CP входу 74HC595
const int clockPin = 12;
//Пин подключен к DS входу 74HC595
const int dataPin = 11; char inputString[2]; void setup() { //устанавливаем режим OUTPUT pinMode(latchPin, OUTPUT); pinMode(dataPin, OUTPUT); pinMode(clockPin, OUTPUT); Serial.begin(9600); Serial.println(“reset”);
} void loop() { // проходим циклом по всем 16 выходам двух регистров for (int thisLed = 0; thisLed < 16; thisLed++) { // записываем сигнал в регистр для очередного светодиода registerWrite(thisLed, HIGH); // если это не первый светодиод, то отключаем предыдущий if (thisLed > 0) { registerWrite(thisLed – 1, LOW); } // если это первый светодиод, то отключаем последний else { registerWrite(15, LOW); } // делаем паузу перед следующией итерацией delay(250); } } // этот метод отсылает бит на сдвиговый регистр void registerWrite(int whichPin, int whichState) { // для хранения 16 битов используем unsigned int unsigned int bitsToSend = 0; // выключаем светодиоды на время передачи битов digitalWrite(latchPin, LOW); // устанавливаем HIGH в соответствующий бит bitWrite(bitsToSend, whichPin, whichState); // разбиваем наши 16 бит на два байта // для записи в первый и второй регистр byte registerOne = highByte(bitsToSend); byte registerTwo = lowByte(bitsToSend); // “проталкиваем” байты в регистры shiftOut(dataPin, clockPin, MSBFIRST, registerTwo); shiftOut(dataPin, clockPin, MSBFIRST, registerOne); // “защелкиваем” регистр, чтобы биты появились на выходах регистра digitalWrite(latchPin, HIGH);
}

Источник: http://arduino.ru/Tutorial/registr_74HC595

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

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

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

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

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

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

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

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

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

Входы 74HC595:

OE

Вход переводящий выходы из высокоимпедансного состояние в рабочее состояние. При логической единице на этом входе выходы 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-х индикаторов будет работать и какую кнопку будем опрашивать. А второй, какие из сегментов загорятся.

Источник: http://HardElectronics.ru/74hc595.html

Знакомство с микросхемой регистра сдвига 74HC595 – управление 16 светодиодами

» Схемы » Применение микроконтроллеров · Начинающим

04-06-2010

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 светодиодах.

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

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

protostack.com

Для комментирования материалов с сайта и получения полного доступа к нашему форуму Вам необходимо зарегистрироваться.
Фрагменты обсуждения: Полный вариант обсуждения »
  • В програмке на 8 светодиодах есть ошибки… Исправьте, плиз…
  • А вы знаете какие именно ошибки в программе. Или пробовали компилировать и получили ошибки при компиляции? Как таковых ошибок в программе нет, но есть один нюанс, который был задуман автором, с целью использовать данный пример на разных контроллерах. Всего навсего… Так же один момент – не указана тактовая частота в программе, но я не считаю что это ошибка, а даже наоборот, с этим параметром можно “поиграться” и увидеть результаты и изменения. Единственное, в тексте описания не говорится о том, что мега настроена на работу от внутреннего осциллятора. У меня скомпилировать получилось, все без ошибок (AVRStudio).
  • Я компелировал в CodeVisionAVR. Ошибки в delay_ms это мелочи, компилятор не понимает _BV() и bit_is_set. Схему тестирую в протеусе. А как в АВРстудио писать на С++, там же вроде ассемблер…
  • AVRStudio + компилятор WinAVR и пишем на Си в студии.
  • Поставил WinAVR, не понимает delay.h Какая библиотека в аврстудио для паузы?
  • Используем: include и include
  • ../new.c:2:26: util/delay.h: No such file or directory :confused: текст программы в АВРСтудио 4: #include #include #define DS_PORT PORTC #define DS_PIN 0 #define ST_CP_PORT PORTC #define ST_CP_PIN 1 #define SH_CP_PORT PORTC #define SH_CP_PIN 2 #define DS_low() DS_PORT&=~_BV(DS_PIN) #define DS_high() DS_PORT|=_BV(DS_PIN) #define ST_CP_low() ST_CP_PORT&=~_BV(ST_CP_PIN) #define ST_CP_high() ST_CP_PORT|=_BV(ST_CP_PIN) #define SH_CP_low() SH_CP_PORT&=~_BV(SH_CP_PIN) #define SH_CP_high() SH_CP_PORT|=_BV(SH_CP_PIN) //Define functions //====================== int i; void ioinit(void); void output_led_state(unsigned char __led_state); //====================== void ioinit (void) { DDRC = 0b00000111; //1 = output, 0 = input PORTC = 0b00000000; } void output_led_state(unsigned char __led_state) { SH_CP_low(); ST_CP_low(); for (i=0;i0; i–) { output_led_state(_BV(i)); _delay_ms(100); } for (i=0; i

Источник: https://www.rlocman.ru/shem/schematics.html?di=65110

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

Сдвиговый регистр — очень распространенное устройство, которое часто применяется для упрощения работы с сегментными индикаторами, с линейками и с матрицами светодиодов.

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

Два таких индикатора займут уже 16 ног Ардуино.

https://www.youtube.com/watch?v=V3FGfl60QHU

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

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

Как правило регистры представляют собой сборку из D-триггеров — элементарных ячеек памяти, с которыми мы уже встречались в отдельном уроке. Записывать данные в регистр можно либо последовательно, либо параллельно.

Регистры первого типа называются сдвиговыми, второго типа — параллельными.

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

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

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

Пусть в начальном состоянии регистр уже заполнен какими-то восемью битами. Попробуем «задвинуть» в него восемь новых бит: 11011010.

Как видно, после двух итераций, в начале регистра оказалось два новых бита, а два бита в последних ячейках «вывалились» через край в небытие. На 8-м шаге весь регистр оказался заполнен новыми битами.

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

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

На этом уроке мы разберем работу сдвигового регистра 74HC595, который может хранить 8 бит данных. Схема выводов микросхемы представлена на картинке. Кстати, у этого регистра есть и отечественный аналог КР1564ИР52.

  • Q0-Q7 — выходы каждой из 8 ячеек;
  • VCC — питание микросхемы, 5В;
  • GND — земля;
  • DS — линия данных;
  • ST_CP — линия синхроимпульса для передачи данных из внутренних ячеек, во внешние;
  • SH_CP — линия синхроимпульса для передачи данных из DS во внутренние ячейки;
  • OE — инверсный, разрешение на вывод данных с внешних ячеек;
  • Out3, Out4 — выводы для подключения второго двигателя;
  • Q7′ — выход регистра, который необходимо соединить с Q0 следующего регистра для создания цепочки.

У регистра есть один вход данных и два входа синхронизации. Синхроимпульс SH_CP запоминает текущее состояние входа данных DS. Другими словами, если на DS в момент синхронизации был высокий уровень HIGH, то в первой ячейке регистра сохранится 1. В противном случае, сохранится .

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

Второй слой ячеек соединяется непосредственно с выходами Q0-Q7, и чтобы переместить бит из первого слоя во второй, нам потребуется второй синхроимпульс ST_CP. Это может немного путать, но зато такой двухслойный регистр дает нам очень полезную возможность.

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

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

Теперь подробнее про алгоритм работы с синхроимпульсами. Вот так выглядит временная диаграмма регистра 74HC595:

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

3. Управление восемью светодиодами

Итак, начнем с самого простого. Будем управлять восемью светодиодами, подключенными к Ардуино Уно посредством сдвигового регистра 74HC595. Не будем забывать, что каждому светодиоду необходим токозадающий резистор. Наличие регистра не освобождает нас от этого важного компонента.

Принципиальная схема

Внешний вид макета

Программа

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

const int data_pin = 2; const int sh_pin = 4; const int st_pin = 3; int bt = 0; void shift(byte v){ for(int i=0; i

Источник: http://robotclass.ru/tutorials/arduino-shift-register/

Программирование Arduino урок 13 — сдвиговый регистр 74HC595

Доброго времени суток! Ситуация, когда в микроконтроллере не хватает выходов, встречается довольно часто. Для решения подобной проблемы воспользуемся сдвиговым регистром 74HC595.

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

Регистр контролирует 8 выходов, занимая всего 3 выхода микроконтроллера. Кроме этого можно собрать каскад из нескольких таких регистров.

Регистр использует принцип синхронизированной последовательной передачи сигнала.

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

Когда байт полностью вычитан, значения всех 8 бит распределяются по выходам регистра. То есть передаем в регистр сигналы последовательно, а на выходах регистра имеем 8-м параллельных сигналов.

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

Выходы регистра могут быть в одном из трёх состояний:

  • логический ноль;
  • логическая единица;
  • высокоомное (высокоимпедансное) состояние.

В высокоомном состоянии выходы отключены от схемы. Отключить можно только все выхода регистра вместе (по одному нельзя).

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

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

Также к земле подключается выход GND. Для нормального функционирования регистра также следует подключить вход MR к рельсе питания. Туда же подключаем Vcc.

К минусам использования сдвигового регистра стоит отнести невозможность использования широтно-импульсной модуляции (ШИМ), потому что выходы регистра могут иметь только логические значения HIGH (1) и LOW (0).

Распиновка входов/выходов регистра

Регистр работает на интерфейсе SPI: выводы DS, ST_CP, SH_CP — это шины управления.

  • Выводы 1-7, 15 ———— Q0-Q7 ———— Параллельные выходы (разряды);
  • Вывод 8 ———————- GND ————— земля;
  • Вывод 9 ———————- Q7″ —————- Выход для последовательного соединения регистров;
  • Вывод 10 ——————— MR —————- Сброс значений регистра. Сброс происходит при получение LOW. Если заведём питание +5В, то сброс будет неактивным;
  • Вывод 11 ——————— SH_CP ———— Вход для тактовых импульсов — «тактовая линия (SCK)»;
  • Вывод 12 ——————— ST_CP ———— Синхронизация выходов — «защёлка (SS)»;
  • Вывод 13 ——————— OE ———— Вход для переключения состояния выходов из высокоомного в рабочее (подключаем на землю);
  • Вывод 14 ——————— DS —————- Вход для последовательных данных — «шина данных (MOSI)»;
  • Вывод 16 ——————— Vcc —————- Питание.

Соберём стенд с одним сдвиговым регистром.

Подключим:

  • GND (пин 8) на землю;
  • Vcc (пин 16) к питанию 5В;
  • OE (пин 13) на землю;
  • MR (пин 10) к питанию 5В;

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

Можно контролировать выводы MR и OE непосредственно с Arduino (обнуляя входы и/или подключая выходы в нужный момент).

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

Схема подключения

Подключаем Arduino:

  • DS (dataPin) 14-й вывод регистра с 11-ым выходом Arduino;
  • SH_CP (clockPin) 11-й вывод регистра с 12-ым выходом Arduino;
  • ST_CP (latchPin) 12-й вывод регистра c 8-ым выходом Arduino;

Конденсатор ёмкостью 0.1 микрофарада необходимо подключит на «защёлку» для минимизации шума в схеме при подаче «защелкивающего» импульса. Подключаем светодиоды к выходам регистра через токоограничивающие резисторы.

Для начала следует отметить, что библиотека SPI в данном примере использоваться не будет.

В место неё будет использовать функцию shiftOut() — выводит байт информации на порт вход/выхода последовательно (побитно).

У функции всего четыре параметра:

  • Номер вывода, по которому передаются данные (подключенный к DS);
  • Номер вывода, по которому передаются тактовые импульсы (подключенный к SH_CP).
  • Параметр передачи битов в регистр: MSBFIRST — прямой порядок, начиная со старшего (первого) бита; LSBFIRST — обратный порядок, начиная с младшего (последнего бита).
  • Значение, которое должно быть передано в регистр. В данном случае передаем значение от 0 до 255 (2 в степени 8, регистр 8-ми битный).

Объявим переменные и присвоим им соответствующие значения.

int latchPin = 8; int clockPin = 12; int dataPin = 11;

Конфигурируем выводы на выход и ставим «защёлку», чтобы сдвиговый регистр не принимал сигналов:

void setup(){   pinMode(clockPin, OUTPUT);   pinMode(dataPin, OUTPUT);   pinMode(latchPin, OUTPUT);   digitalWrite(latchPin, HIGH); }

После этого отправим на регистр байт. Для этого снимем защёлку (ставим LOW) — начинаём передачу данных (регистр принимает сигналы с Arduino).

digitalWrite(latchPin, LOW);

Отправляем данные (отправляем байт в цифровом или двоичном виде) = 0b00000001.

shiftOut(dataPin, clockPin, MSBFIRST,0b00000001);

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

digitalWrite(latchPin, HIGH);

В итоге весь наш код имеет следующий вид:

int latchPin = 8; int clockPin = 12; int dataPin = 11;  void setup() {   pinMode(clockPin, OUTPUT);   pinMode(dataPin, OUTPUT);   pinMode(latchPin, OUTPUT);   digitalWrite(latchPin, HIGH); }  void loop() {   digitalWrite(latchPin, LOW);   shiftOut(dataPin, clockPin, MSBFIRST, 0b00000001);   digitalWrite(latchPin, HIGH); }

Заливаем прошивку в контроллер. Смотрим на результат.

Непосредственно управление регистром осуществляется с помощью входов DS, SH_CP и ST_CP. Когда происходит переключение SH_CP (clockPin) с LOW на HIGH, в регистр считывается значение с DS (1 бит). При переключении ST_CP (latchPin) с LOW на HIGH заканчивается прием информации и выводы переходят в назначенное состояние.

Напишем функцию (вместо 3-х строк) для оптимизации кода:

void sendBitsToShift (byte value){   digitalWrite(latchPin, LOW);   shiftOut(dataPin, clockPin, MSBFIRST, value);   digitalWrite(latchPin, HIGH); }

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

Для удобства работы создадим массив типа «boolean» для хранения состояния разряда (HIGH или LOW).

boolean statesOfpin[8];

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

void sendBitsToPin (int pin, boolean state){

Микроконтроллер начинает отсчёт с нуля. Чтобы не было путаницы будем отнимать единицу от номера текущего разряда. Другими словами — пользователь работает с 1 — 8 разрядами, а контроллер воспринимает это, как работу с 0 — 7.

 pin–;

Перезаписываем изменения в массиве:

statesOfpin [pin] = state;

Формируем байт (из 8 битов) и отправляем его на регистр. Объявляем переменные: value — формируемый байт (по умолчанию с нулевым значением); add — хранить байт текущего разряда.

  byte value = 0;   byte add = 1;

Формируем байт.

  for(int i=0; i

Источник: http://mozgochiny.ru/electronics-2/programmirovanie-arduino-urok-13-sdvigovyiy-registr-74hc595/

Управление по одному проводу семисегментным дисплеем на сдвиговых регистрах 74HC595 — Сообщество «Радиокружок» на DRIVE2

Достаточно часто у любителей микроконтроллеров возникает проблема с нехваткой выводов. Обычно для расширения портов ввода/вывода используют сдвиговые регистры типа 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. Думаю, что по комментариям все понятно.

Источник: https://www.drive2.ru/c/469629454843380044/

Когда не хватает ног. Часть 2. Сдвиговый регистр 74HC595

Источник: http://AVRproject.ru/publ/kak_podkljuchit/bascom_avr_74hc595/2-1-0-44

Ссылка на основную публикацию
Adblock
detector
",css:{backgroundColor:"#000",opacity:.6}},container:{block:void 0,tpl:"
"},wrap:void 0,body:void 0,errors:{tpl:"
",autoclose_delay:2e3,ajax_unsuccessful_load:"Error"},openEffect:{type:"fade",speed:400},closeEffect:{type:"fade",speed:400},beforeOpen:n.noop,afterOpen:n.noop,beforeClose:n.noop,afterClose:n.noop,afterLoading:n.noop,afterLoadingOnShow:n.noop,errorLoading:n.noop},o=0,p=n([]),h={isEventOut:function(a,b){var c=!0;return n(a).each(function(){n(b.target).get(0)==n(this).get(0)&&(c=!1),0==n(b.target).closest("HTML",n(this).get(0)).length&&(c=!1)}),c}},q={getParentEl:function(a){var b=n(a);return b.data("arcticmodal")?b:(b=n(a).closest(".arcticmodal-container").data("arcticmodalParentEl"),!!b&&b)},transition:function(a,b,c,d){switch(d=null==d?n.noop:d,c.type){case"fade":"show"==b?a.fadeIn(c.speed,d):a.fadeOut(c.speed,d);break;case"none":"show"==b?a.show():a.hide(),d();}},prepare_body:function(a,b){n(".arcticmodal-close",a.body).unbind("click.arcticmodal").bind("click.arcticmodal",function(){return b.arcticmodal("close"),!1})},init_el:function(d,a){var b=d.data("arcticmodal");if(!b){if(b=a,o++,b.modalID=o,b.overlay.block=n(b.overlay.tpl),b.overlay.block.css(b.overlay.css),b.container.block=n(b.container.tpl),b.body=n(".arcticmodal-container_i2",b.container.block),a.clone?b.body.html(d.clone(!0)):(d.before("
"),b.body.html(d)),q.prepare_body(b,d),b.closeOnOverlayClick&&b.overlay.block.add(b.container.block).click(function(a){h.isEventOut(n(">*",b.body),a)&&d.arcticmodal("close")}),b.container.block.data("arcticmodalParentEl",d),d.data("arcticmodal",b),p=n.merge(p,d),n.proxy(e.show,d)(),"html"==b.type)return d;if(null!=b.ajax.beforeSend){var c=b.ajax.beforeSend;delete b.ajax.beforeSend}if(null!=b.ajax.success){var f=b.ajax.success;delete b.ajax.success}if(null!=b.ajax.error){var g=b.ajax.error;delete b.ajax.error}var j=n.extend(!0,{url:b.url,beforeSend:function(){null==c?b.body.html("
"):c(b,d)},success:function(c){d.trigger("afterLoading"),b.afterLoading(b,d,c),null==f?b.body.html(c):f(b,d,c),q.prepare_body(b,d),d.trigger("afterLoadingOnShow"),b.afterLoadingOnShow(b,d,c)},error:function(){d.trigger("errorLoading"),b.errorLoading(b,d),null==g?(b.body.html(b.errors.tpl),n(".arcticmodal-error",b.body).html(b.errors.ajax_unsuccessful_load),n(".arcticmodal-close",b.body).click(function(){return d.arcticmodal("close"),!1}),b.errors.autoclose_delay&&setTimeout(function(){d.arcticmodal("close")},b.errors.autoclose_delay)):g(b,d)}},b.ajax);b.ajax_request=n.ajax(j),d.data("arcticmodal",b)}},init:function(b){if(b=n.extend(!0,{},a,b),!n.isFunction(this))return this.each(function(){q.init_el(n(this),n.extend(!0,{},b))});if(null==b)return void n.error("jquery.arcticmodal: Uncorrect parameters");if(""==b.type)return void n.error("jquery.arcticmodal: Don't set parameter \"type\"");switch(b.type){case"html":if(""==b.content)return void n.error("jquery.arcticmodal: Don't set parameter \"content\"");var e=b.content;return b.content="",q.init_el(n(e),b);case"ajax":return""==b.url?void n.error("jquery.arcticmodal: Don't set parameter \"url\""):q.init_el(n("
"),b);}}},e={show:function(){var a=q.getParentEl(this);if(!1===a)return void n.error("jquery.arcticmodal: Uncorrect call");var b=a.data("arcticmodal");if(b.overlay.block.hide(),b.container.block.hide(),n("BODY").append(b.overlay.block),n("BODY").append(b.container.block),b.beforeOpen(b,a),a.trigger("beforeOpen"),"hidden"!=b.wrap.css("overflow")){b.wrap.data("arcticmodalOverflow",b.wrap.css("overflow"));var c=b.wrap.outerWidth(!0);b.wrap.css("overflow","hidden");var d=b.wrap.outerWidth(!0);d!=c&&b.wrap.css("marginRight",d-c+"px")}return p.not(a).each(function(){var a=n(this).data("arcticmodal");a.overlay.block.hide()}),q.transition(b.overlay.block,"show",1*")),b.overlay.block.remove(),b.container.block.remove(),a.data("arcticmodal",null),n(".arcticmodal-container").length||(b.wrap.data("arcticmodalOverflow")&&b.wrap.css("overflow",b.wrap.data("arcticmodalOverflow")),b.wrap.css("marginRight",0))}),"ajax"==b.type&&b.ajax_request.abort(),p=p.not(a))})},setDefault:function(b){n.extend(!0,a,b)}};n(function(){a.wrap=n(document.all&&!document.querySelector?"html":"body")}),n(document).bind("keyup.arcticmodal",function(d){var a=p.last();if(a.length){var b=a.data("arcticmodal");b.closeOnEsc&&27===d.keyCode&&a.arcticmodal("close")}}),n.arcticmodal=n.fn.arcticmodal=function(a){return e[a]?e[a].apply(this,Array.prototype.slice.call(arguments,1)):"object"!=typeof a&&a?void n.error("jquery.arcticmodal: Method "+a+" does not exist"):q.init.apply(this,arguments)}}(jQuery)}var debugMode="undefined"!=typeof debugFlatPM&&debugFlatPM,duplicateMode="undefined"!=typeof duplicateFlatPM&&duplicateFlatPM,countMode="undefined"!=typeof countFlatPM&&countFlatPM;document["wri"+"te"]=function(a){let b=document.createElement("div");jQuery(document.currentScript).after(b),flatPM_setHTML(b,a),jQuery(b).contents().unwrap()};function flatPM_sticky(c,d,e=0){function f(){if(null==a){let b=getComputedStyle(g,""),c="";for(let a=0;a=b.top-h?b.top-h{const d=c.split("=");return d[0]===a?decodeURIComponent(d[1]):b},""),c=""==b?void 0:b;return c}function flatPM_testCookie(){let a="test_56445";try{return localStorage.setItem(a,a),localStorage.removeItem(a),!0}catch(a){return!1}}function flatPM_grep(a,b,c){return jQuery.grep(a,(a,d)=>c?d==b:0==(d+1)%b)}function flatPM_random(a,b){return Math.floor(Math.random()*(b-a+1))+a}
");let k=document.querySelector(".flat_pm_modal[data-id-modal=\""+a.ID+"\"]");if(-1===d.indexOf("go"+"oglesyndication")?flatPM_setHTML(k,d):jQuery(k).html(b+d),"px"==a.how.popup.px_s)e.bind(h,()=>{e.scrollTop()>a.how.popup.after&&(e.unbind(h),f.unbind(i),j())}),void 0!==a.how.popup.close_window&&"true"==a.how.popup.close_window&&f.bind(i,()=>{e.unbind(h),f.unbind(i),j()});else{let b=setTimeout(()=>{f.unbind(i),j()},1e3*a.how.popup.after);void 0!==a.how.popup.close_window&&"true"==a.how.popup.close_window&&f.bind(i,()=>{clearTimeout(b),f.unbind(i),j()})}f.on("click",".flat_pm_modal .flat_pm_crs",()=>{jQuery.arcticmodal("close")})}if(void 0!==a.how.outgoing){let b,c="0"==a.how.outgoing.indent?"":" style=\"bottom:"+a.how.outgoing.indent+"px\"",e="true"==a.how.outgoing.cross?"":"",f=jQuery(window),g="scroll.out"+a.ID,h=void 0===flatPM_getCookie("flat_out_"+a.ID+"_mb")||"false"!=flatPM_getCookie("flat_out_"+a.ID+"_mb"),i=document.createElement("div"),j=jQuery("body"),k=()=>{void 0!==a.how.outgoing.cookie&&"false"==a.how.outgoing.cookie&&h&&(jQuery(".flat_pm_out[data-id-out=\""+a.ID+"\"]").addClass("show"),j.on("click",".flat_pm_out[data-id-out=\""+a.ID+"\"] .flat_pm_crs",function(){flatPM_setCookie("flat_out_"+a.ID+"_mb",!1)})),(void 0===a.how.outgoing.cookie||"false"!=a.how.outgoing.cookie)&&jQuery(".flat_pm_out[data-id-out=\""+a.ID+"\"]").addClass("show")};switch(a.how.outgoing.whence){case"1":b="top";break;case"2":b="bottom";break;case"3":b="left";break;case"4":b="right";}jQuery("body > *").eq(0).before("
"+e+"
");let m=document.querySelector(".flat_pm_out[data-id-out=\""+a.ID+"\"]");-1===d.indexOf("go"+"oglesyndication")?flatPM_setHTML(m,d):jQuery(m).html(e+d),"px"==a.how.outgoing.px_s?f.bind(g,()=>{f.scrollTop()>a.how.outgoing.after&&(f.unbind(g),k())}):setTimeout(()=>{k()},1e3*a.how.outgoing.after),j.on("click",".flat_pm_out .flat_pm_crs",function(){jQuery(this).parent().removeClass("show").addClass("closed")})}countMode&&(flat_count["block_"+a.ID]={},flat_count["block_"+a.ID].count=1,flat_count["block_"+a.ID].click=0,flat_count["block_"+a.ID].id=a.ID)}catch(a){console.warn(a)}}function flatPM_start(){let a=flat_pm_arr.length;if(0==a)return flat_pm_arr=[],void jQuery(".flat_pm_start, .flat_pm_end").remove();flat_body=flat_body||jQuery("body"),!flat_counter&&countMode&&(flat_counter=!0,flat_body.on("click","[data-flat-id]",function(){let a=jQuery(this),b=a.attr("data-flat-id");flat_count["block_"+b].click++}),flat_body.on("mouseenter","[data-flat-id] iframe",function(){let a=jQuery(this),b=a.closest("[data-flat-id]").attr("data-flat-id");flat_iframe=b}).on("mouseleave","[data-flat-id] iframe",function(){flat_iframe=-1}),jQuery(window).on("beforeunload",()=>{jQuery.isEmptyObject(flat_count)||jQuery.ajax({async:!1,type:"POST",url:ajaxUrlFlatPM,dataType:"json",data:{action:"flat_pm_ajax",data_me:{method:"flat_pm_block_counter",arr:flat_count}}})}).on("blur",()=>{-1!=flat_iframe&&flat_count["block_"+flat_iframe].click++})),flat_userVars.init();for(let b=0;bflat_userVars.textlen||void 0!==a.chapter_sub&&a.chapter_subflat_userVars.titlelen||void 0!==a.title_sub&&a.title_subc&&cc&&c>d&&(b=flatPM_addDays(b,-1)),b>e||cd||c-1!=flat_userVars.referer.indexOf(a))||void 0!==a.referer.referer_disabled&&-1!=a.referer.referer_disabled.findIndex(a=>-1!=flat_userVars.referer.indexOf(a)))&&(c=!0),c||void 0===a.browser||(void 0===a.browser.browser_enabled||-1!=a.browser.browser_enabled.indexOf(flat_userVars.browser))&&(void 0===a.browser.browser_disabled||-1==a.browser.browser_disabled.indexOf(flat_userVars.browser)))){if(c&&void 0!==a.browser&&void 0!==a.browser.browser_enabled&&-1!=a.browser.browser_enabled.indexOf(flat_userVars.browser)&&(c=!1),!c&&(void 0!==a.geo||void 0!==a.role)&&(""==flat_userVars.ccode||""==flat_userVars.country||""==flat_userVars.city||""==flat_userVars.role)){flat_pm_then.push(a),flatPM_setWrap(a),flat_body.hasClass("flat_pm_block_geo_role")||(flat_body.addClass("flat_pm_block_geo_role"),flatPM_ajax("flat_pm_block_geo_role")),c=!0}c||(flatPM_setWrap(a),flatPM_next(a))}}}let b=jQuery(".flatPM_sticky");b.each(function(){let a=jQuery(this),b=a.data("height")||350,c=a.data("top");a.wrap("
");let d=a.parent()[0];flatPM_sticky(this,d,c)}),debugMode||countMode||jQuery("[data-flat-id]:not([data-id-out]):not([data-id-modal])").contents().unwrap(),flat_pm_arr=[],jQuery(".flat_pm_start, .flat_pm_end").remove()}
 

 В прошлый раз был рассмотрен вариант увеличения выходов микроконтроллера при помощи микросхемы – дешифратора , сегодня рассмотрим более продвинутый вариант на сдвиговом регистре 74HC595.

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

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

 Итак, рассмотрим более подробно назначение выводов микросхемы и научимся управлять сдвиговым регистром 74hc595 в Bascom-AVR.

 Для начала ознакомимся с выводами микросхемы, а точнее с их функциональностью. Ниже представлена вырезка из даташита на 74hc595 с обозначением выводов микросхемы:

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

  • MR – сброс регистра.

  • SH_CP – вход для тактовых импульсов
  • ST_CP – вход «защёлкивающий» данные
  • OE – вход переводящий выходы из HI-Z в рабочее состояние 
  • DS – вход данных
  • VCC – питание 5 вольт

 Логика работы с регистром

 Когда на тактовом входе SH_CP появляется логическая единица, бит находящийся на входе данных DS считывается и записывается в сдвиговый регистр. Этот бит записывается в самый младший разряд.

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

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

Что бы данные появились на выходах Q0…Q7 нужно их «защёлкнуть». Для этого необходимо подать логическую единицу на вход ST_CP

 – MR осуществляет сброс регистра, устанавливая все выходы Q0…Q7 в состояние логического нуля.

Для осуществления сброса нужно подать логический ноль на этот вход и подать положительный импульс на вход ST_CP.

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

 – OE (output enable) если подать сюда логическую 1, то выходы будут находится в высокоомном HI-Z состоянии. Когда подаем на этот вход логический 0, выходы будут находится в рабочем состоянии.

 – Q7′  предназначен для последовательного соединения сдвиговых регистров.

 Но лучше один раз увидеть, чем два раза прочитать =) поэтому смотрим на анимацию:

 Работа с регистром в лоб

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

$regfile = “attiny2313.

dat”
$crystal = 1000000

Config Portb = Output

Sh_cp Alias Portb.3                'нога для тактовых импульсов
Ds Alias Portb.2                   'нога для вывода данных
St_cp Alias Portb.

0               'нога для “защелкивания” данных в регистр хранения
'вывод через регистр числа 146 (в бинарном представлении 10010010)

St_cp = 0                          'выставляем ногу в режим записи данных

Ds = 1                             'выставляем первый бит
Sh_cp = 0                          'даем импульс на тактовый выход
Sh_cp = 1

Ds = 0                             'выставляем второй бит
Sh_cp = 0
Sh_cp = 1

Ds = 0                             'выставляем третий бит
Sh_cp = 0
Sh_cp = 1

Ds = 1                             'выставляем четвертый бит
Sh_cp = 0
Sh_cp = 1

Ds = 0                             'выставляем пятый бит
Sh_cp = 0
Sh_cp = 1

Ds = 0                             'выставляем шестой бит
Sh_cp = 0
Sh_cp = 1

Ds = 1                             'выставляем седьмой бит
Sh_cp = 0
Sh_cp = 1

Ds = 0                             'выставляем восьмой бит
Sh_cp = 0
Sh_cp = 1

St_cp = 1                          'защелкиваем введенные данные

End

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

Работает, на выходе регистра появилось отправленное число!

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

Управление регистром 74HC595 в Bascom через команду ShiftOut

 В Bascom-AVR для работы со всевозможными последовательными интерфейсами есть замечательная команда SHIFTOUT
 Эта команда сама разложит число на битовые составляющие и последовательно выведет их на любой пин микроконтроллера, заодно она может выдавать тактовые импульсы. Для работы со сдвиговыми регистрами самое то! Синтаксис команды:

Datapin , Clockpin , var , option

Datapin – порт микроконтроллера для вывода данных

Clockpin – порт микроконтроллера для вывода тактовых импульсов

Var – данные которые хотим отправить в регистр

Option – число от 0 до 3, этим параметром выбирается в каком порядке будут вводиться данные в регистр и активный уровень на линии Clock при котором происходит запись бита:
option=0 – старший бит идет первым, Clock активный уровень низкий
option=1 – старший бит идет первым, Clock активный уровень высокий
option=2 – младший бит идет первым, Clock активный уровень низкий
option=3 – младший бит идет первым, Clock   активный уровень высокий

В нашем случае для работы с регистром 74HC595 параметр option нужно ставить 1 или 3.

 Для того чтобы защелкнуть данные в регистре, применим команду PulseOut. Эта команда выводит импульс на ногу микроконтроллера с заданной длительностью. Конфигурация команды выглядит следующим образом:

здесь выводится импульс на PortB.0 длительностью 5 микросекунд (при частоте работы мк 4 МГц)

 Теперь давайте выведем число 10010001 (145 в десятичной системе) на выход регистра, подключенному к микроконтроллеру по вышеприведенной схеме:

$regfile = “attiny2313.

dat”
$crystal = 1000000

Dim A As Byte
Config Portb = Output

A = 145

Gosub Hc595                                 'уходим на подпрограмму отправки данных

End

Hc595:                                      'подпрограмма отправки данных

Shiftout Portb.2 , Portb.3 , A , 1          'отправляем данные в регистр
Pulseout Portb , 0 , 5                      'защелкиваем данные
Return

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

Как видно управление сдвиговым регистром 74HC595 в Bascom состоит всего из двух строк кода, и не представляет никаких сложностей.

Увеличение разрядности

 Как говорилось ранее, регистры могут легко состыковаться друг с другом, тем самым давая возможность увеличить количество портов вывода практически до бесконечности.
 Для того чтобы добавить дополнительный регистр, необходимо соединить вместе выводы для тактовых импульсов SH_CP и выводы для защелкивания данных ST_CP. Вход данных первого регистра подключается к микроконтроллеру и туда мы будем гнать данные, а вход второго регистра соединяется к выводу Q7’ первого регистра.
 В программе управления необходимо изменить тип переменной, которую будем выводить через регистры. Так как соединив вместе два регистра мы получили в управление 16 ножек, то переменная должна хранить 16 бит данных (или 2 байта). Такой объем данных хранит переменная типа Word. Этот тип мы и будем использовать, и для примера выведем число 1111001001001100 (в десятичном виде это будет число 62028). 

$regfile = “attiny2313.

dat”
$crystal
 = 1000000

Dim A As Word                                     'выбираем 2х байтный тип переменной

A = 62028                                         'выведем вот это числоShiftout Portb.2 , Portb.3 , A , 1                'отправляем данные в регистрPulseout Portb , 0 , 5                            'защелкиваем данные

 Старший байт (левая часть 11110010) выводится через второй регистр (IC2), а младший байт (01001100) выводится через первый регистр, соединенный к микроконтроллеру напрямую (IC1).

 Думаю проблем с подключением 3, 4, 5 регистров в ряд возникнуть не должно 😉

Удачи!