Применение сдвигового регистра CD74HC595

Тема в разделе "Схемотехника, компоненты, модули", создана пользователем OOM, 7 янв 2017.

  1. OOM

    OOM Нерд

    Всем доброго времени суток! Проблема следующего характера. Хочу использовать сдвиговый регистр 74HC595 как увеличитель портов. В интернете много информации по нему, но там только указано как запустить бегущие огоньки по светодиодам, а мне нужно, что бы при нажатии на кнопку срабатывал определенный выход регистра. Планирую использовать каскад из 3 или 4 регистров. Подскажите пожалуйста как это можно реализовать, очень нужно. Заранее спасибо.
     
  2. mcureenab

    mcureenab Гуру

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

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

    ostrov Гуру

    Вот тут хороший пример использования сдвигового регистра. Собрать каскадом ненамного сложнее.
     
  4. ANV

    ANV Гуру

    Только от принципиальной схемы кровь глазами чуть не пошла, пока не понял что у пересечения 8 и 13 вывода точку не нарисовали
     
  5. ostrov

    ostrov Гуру

    На картинке ниже хорошо нарисовано.
     
  6. ANV

    ANV Гуру

    К вам претензий то нет никаких, но надо чтобы Амперка это исправила.
    И уж извините, но я марвелловские фритцинговые комиксы не смотрю, это не документация.
     
  7. OOM

    OOM Нерд

    Если я правильно понял из Вашего примера, кнопка последовательно включает пины регистра, тем самым на семисегментнике миняются цифры. А как эти пины регистра включать избирательно (т.е 1 или 5 или 15)
     
  8. ostrov

    ostrov Гуру

    Формируете байт, в котором каждый бит это состояние соответствующего пина регистра, и отправляете его в регистр.
     
  9. OOM

    OOM Нерд

    Вот нашарил код.


    Код (Text):

    int dataPin = 11;      // pin 14 on the 74HC595
    int latchPin = 8;      // pin 12 on the 74HC595
    int clockPin = 12;      // pin 11 on the 74HC595
    int Btn1 = 5;
    int Btn2 = 6;
    int Btn3 = 7;

    int pin1 = 0;
    int pin2 = 0;
    int pin3 = 0;
    int pin4 = 0;
    int pin5 = 0;
    int pin6 = 0;
    int pin7 = 0;
    int pin8 = 0;

    void setup()
    {
      pinMode(dataPin, OUTPUT);
      pinMode(latchPin, OUTPUT);
      pinMode(clockPin, OUTPUT);
      pinMode(Btn1, INPUT_PULLUP);
      pinMode(Btn2, INPUT_PULLUP);
      pinMode(Btn3, INPUT_PULLUP);
    }

    void loop() {

      {
        if (digitalRead(Btn1) == HIGH) {
          pin1 = (HIGH);
          pin2 = (HIGH);
          pin3 = (HIGH);
        }
        else {
          pin1 = (LOW);
          pin2 = (LOW);
          pin3 = (LOW);
        }

        if (digitalRead(Btn2) == HIGH) {
          pin4 = (HIGH);
          pin5 = (HIGH);
          pin6 = (HIGH);
        }
        else {
          pin4 = (LOW);
          pin5 = (LOW);
          pin6 = (LOW);
        }

        if (digitalRead(Btn3) == HIGH) {
          pin7 = (HIGH);
          pin8 = (HIGH);
        }
        else {
          pin7 = (LOW);
          pin8 = (LOW);
        }
      }

      {
        digitalWrite(clockPin, LOW);
        digitalWrite(dataPin, pin1);
        digitalWrite(latchPin, LOW);
        digitalWrite(latchPin, HIGH);

        digitalWrite(dataPin, pin2);
        digitalWrite(latchPin, LOW);
        digitalWrite(latchPin, HIGH);

        digitalWrite(dataPin, pin3);
        digitalWrite(latchPin, LOW);
        digitalWrite(latchPin, HIGH);

        digitalWrite(dataPin, pin4);
        digitalWrite(latchPin, LOW);
        digitalWrite(latchPin, HIGH);

        digitalWrite(dataPin, pin5);
        digitalWrite(latchPin, LOW);
        digitalWrite(latchPin, HIGH);

        digitalWrite(dataPin, pin6);
        digitalWrite(latchPin, LOW);
        digitalWrite(latchPin, HIGH);

        digitalWrite(dataPin, pin7);
        digitalWrite(latchPin, LOW);
        digitalWrite(latchPin, HIGH);

        digitalWrite(dataPin, pin8);
        digitalWrite(latchPin, LOW);
        digitalWrite(latchPin, HIGH);
        digitalWrite(clockPin, HIGH);

      }
    }

    Проверил, работает, но очень громоздкий получится если подключить еще три региста. У кого будут какие мысли, что бы его сделать как то более компактным.
     
  10. mcureenab

    mcureenab Гуру

    Прочтите документацию, чтобы не тиражировать говнокод.

    https://www.arduino.cc/en/Reference/ShiftOut

    Код (C++):
    void shiftOut(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, uint8_t val);
     
     
    Последнее редактирование: 7 янв 2017
  11. mcureenab

    mcureenab Гуру

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

    ostrov Гуру

    Еще лучше написать эту функцию самостоятельно и через PORT, будет выполняться в сто раз быстрее. Но ShiftOut всеравно лучше чем индийский код.
     
  13. OOM

    OOM Нерд

    А не подскажите как это сделать. Я в этом не силен.
     
  14. mcureenab

    mcureenab Гуру

    Оставьте это тем, кто силен.
    Просто заведите массив с количеством элементов равным количеству микросхем в каскаде:
    uint8_t regs[] = {0};
    Тут одна МС.
    Выставляйте в нужных ячейках массива нужные биты и прокручивайте их в цикле подряд функцией shiftOut.
    Не забудьте отключать и подключать выходы регистров во время прокрутки.
     
  15. ostrov

    ostrov Гуру

    Один байт это и есть массив из 8 бит. То есть состояние 8 пинов одного регистра.
     
  16. mcureenab

    mcureenab Гуру

    Только доступ к элементам не по индексу в квадратных скобках, а макросами
     
  17. ostrov

    ostrov Гуру

    Вот тут с примером написано как выводить биты байта в регистр. Об одном и том же пятый раз говорим. Почему не взять пример и не попробовать? Поэксперементировать. Многое станет понятно.
     
  18. mcureenab

    mcureenab Гуру

    А при чем тут биты байта? Чтобы биты байта в регистр отправить, их нужно приготовить - установить в 0 или 1.
    И типы параметров там неправильно указаны. Не int а uint8_t.
     
  19. ostrov

    ostrov Гуру

    Способов тому сотня и один. Самые кошерные это сдвиг и битовая логика. Ссылки давать не буду, тысячи их.
     
  20. ostrov

    ostrov Гуру