Работа с микросхемой SN74HC595N

Тема в разделе "Схемотехника, компоненты, модули", создана пользователем Kremnev8, 25 авг 2015.

  1. Kremnev8

    Kremnev8 Нуб

    Подключил две микросхемы одному гайду , все работает с помощью скетча от туда же.
    однако мне такой метод вообше не нравится поэтому написал немного другой. с одной микросхемой работает , но стоит подключить вторую первая группа светодиодов работает нормально , а вот вторая начинает ели мелькать и сразу гаснуть.
    Вот так подключил:
    Подключение2.png
    вот скетч, написанный мной
    Код (Text):

    #include <SPI.h>

    enum { REG_SELECT = 2 }; // пин, управляющий защёлкой (SS в терминах SPI)
    uint16_t Lbit;
    uint16_t BitNum[] = {1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768};
    bool StateNum[] = {false,false,false,false,false,false,false,false,false};
    bool StateNum16[] = {false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false};
    uint16_t Sbit = 0;


    void setup()
    {
      SPI.begin();
      Serial.begin(9600);
      Serial.println("SETUP");
      Serial.println(toBool(false));
      Serial.println(toBool(true));
      Serial.println("SETUP END");
      pinMode(REG_SELECT, OUTPUT);
      Clear16(REG_SELECT);
    // Regset(2,1,true);
    // Regset(2,3,true);
    // Regset(2,5,true);
    // Regset(2,7,true);
    }

    String toBool(int Bool)
    {
      if (Bool == 0)
      {
        return "false";
      }else
      {
        return "true";
      }
    }

    void Clear8(int SS)
    {
      digitalWrite(SS, LOW);
      Transfer(0);
      for (int i=0;i<8;i++)
      {
      StateNum[i] = false;
      }
      digitalWrite(SS, HIGH);
    }

    void Clear16(int SS)
    {
      digitalWrite(SS, LOW);
      Transfer(highByte(0));
      Serial.print("highBite ");
      Serial.println(highByte(0));
      Transfer(lowByte(0));
      Serial.print("lowBite ");
      Serial.println(lowByte(0));
      for (int i=0;i<16;i++)
      {
      StateNum16[i] = false;
      }
      digitalWrite(SS, HIGH);
    }



    void Regset8(int SS,int pin,bool state)
    {
      if (state)
      {
      if (StateNum[pin-1]==false)
      {
      Sbit = Lbit + BitNum[pin-1];
      StateNum[pin-1] = true;
      }
      }else
      {
        if (StateNum[pin-1]==true)
      {
      Sbit = Lbit - BitNum[pin-1];
      StateNum[pin-1] = false;
      }
      }
      digitalWrite(SS, LOW);
      //Serial.println(Sbit);
      Transfer(Sbit);
      digitalWrite(SS, HIGH);
    }

    void Regset16(int SS,int pin,bool state)
    {
      if (state)
      {
      if (StateNum16[pin-1]==false)
      {
      Sbit = Lbit + BitNum[pin-1];
      StateNum16[pin-1] = true;
      }
      }else
      {
        if (StateNum16[pin-1]==true)
      {
      Sbit = Lbit - BitNum[pin-1];
      StateNum16[pin-1] = false;
      }
      }
      digitalWrite(SS, LOW);
      //Serial.println(Sbit);

      Transfer(highByte(Sbit));
      Serial.print("highBite ");
      Serial.println(highByte(Sbit));
      Transfer(lowByte(Sbit));
      Serial.print("lowBite ");
      Serial.println(lowByte(Sbit));
      digitalWrite(SS, HIGH);
    }

    void Transfer(uint16_t Bit)
    {
      SPI.transfer(Bit);
      //Serial.println(Bit);
      Lbit = Bit;
    }


    void loop()
    {

      //Regset(2,,);
      Clear16(2);
      Regset16(2,1,true);
      Regset16(2,3,true);
      Regset16(2,5,true);
      Regset16(2,7,true);
      Regset16(2,9,true);
      Regset16(2,11,true);
      Regset16(2,13,true);
      Regset16(2,15,true);

      delay(1000 / 2);

      Clear16(2);
      Regset16(2,2,true);
      Regset16(2,4,true);
      Regset16(2,6,true);
      Regset16(2,8,true);
      Regset16(2,10,true);
      Regset16(2,12,true);
      Regset16(2,14,true);
      Regset16(2,16,true);
      delay(1000 / 2);

    }
     
    Может кто нибудь помочь с этой микросхемой?
     
    Последнее редактирование: 26 авг 2015
  2. AlexU

    AlexU Гуру

    Навскидку....
    В схеме не вижу подключения "земли" (вывод 8 микросхем).
    Микросхемы "не связаны" через пин 9 -- светодиоды на обоих микросхемах должны гореть одинаково.
    C SPI на практике пока не связывался, но судя по тому, что знаю, в Arduino UNO интерфейс SPI использует пины 11, 12, 13, 10 (https://www.arduino.cc/en/Reference/SPI). Вы же в схеме используете пин 2.
     
  3. Kremnev8

    Kremnev8 Нуб

    по началу я подключал к 8 пину землю однако потом заметил что сверху тоже можно подать землю.
    судя по гайду если связать 9(1) и 14(2) пины на микросхемах то они должны стать кластером. SPI подключен правильно , 2 пин это "защелка" , выбор устройства для управления.
     
  4. AlexU

    AlexU Гуру

    Как и где заметили? Если по поводу пина 13 (!OE) микросхем (в Вашей схеме он подключен на землю), то он отвечает за активацию выходов, и к "земле" отношения не имеет. На "землю" этот пин подключается для активации выходов.
    Подключите 8-й пин микросхем к "земле".

    Хоть это и противоречит ссылке, приведенной мной в предыдущем посте, спорить не буду, т.к. на практике не сталкивался, только в теории.
     
  5. Kremnev8

    Kremnev8 Нуб

    Я это заметил случайно не подключив нижний ряд питания , но светодиоды работали . поэтому и решил что можно от туда дать землю.
     
  6. AlexU

    AlexU Гуру

    Да еще со скетчем не много "перемудрили". Почему бы не взять, например, два 8-ми битных числа или одно 16-и битное для хранения состояний, вместо массивов StateNum и StateNum16. Также можно было обойтись и без массива BitNum, который хранит степени двойки.
    Пример операций с битами:
    Код (Text):

    char i = 0;
    i |= 1; // установка 0-го бита переменной i в 1
    i |= 1 << 3; // установка 3-го бита в 1 (отсчет с 0, т.е. первый бит -- это нулевой)
    i &= ~(1 << 4); // Сброс 4-го бита в 0

    char s = 0;
    s = i & (1 << 5); // s != 0, если 5-й бит переменной i установлен в 1, иначе 0
     
     
  7. Kremnev8

    Kremnev8 Нуб

    Спасибо!
    с помощью более продвинутых методов , массив регистров стал работать правильно
    Код (Text):
    #include <SPI.h>

    enum { REG = 2 };
    uint16_t Sbit = 0;


    void setup()
    {
      SPI.begin();
      Serial.begin(9600);
      pinMode(REG, OUTPUT);
      Clear(REG_SELECT);
    }

    String toBool(int Bool)
    {
      if (Bool == 0)
      {
        return "false";
      }else
      {
        return "true";
      }
    }

    void Clear(int SS)
    {
      digitalWrite(SS, LOW);
      SPI.transfer(highByte(0));
      SPI.transfer(lowByte(0));
      digitalWrite(SS, HIGH);
      for (int i=0;i<16;i++)
      {
        Serial.print("clearing pin");
        Serial.println(i);
        Sbit &= ~(1 << i);
      }
    }

    void Regset8(int SS,int pin,bool state)
    {
      Sbit |= state << pin-1;
      digitalWrite(SS, LOW);
      SPI.transfer(Sbit);
      digitalWrite(SS, HIGH);
    }

    void Regset16(int SS,int pin,bool state)
    {
        Sbit |= state << pin-1;
      digitalWrite(SS, LOW);
      SPI.transfer(highByte(Sbit));
      SPI.transfer(lowByte(Sbit));
      digitalWrite(SS, HIGH);
    }



    void loop()
    {
     
      Clear(REG);
      Regset16(REG,1,true);
      Regset16(REG,3,true);
      Regset16(REG,5,true);
      Regset16(REG,7,true);
      Regset16(REG,9,true);
      Regset16(REG,11,true);
      Regset16(REG,13,true);
      Regset16(REG,15,true);
      delay(1000 / 2);
      Clear(REG);
      Regset16(REG,2,true);
      Regset16(REG,4,true);
      Regset16(REG,6,true);
      Regset16(REG,8,true);
      Regset16(REG,10,true);
      Regset16(REG,12,true);
      Regset16(REG,14,true);
      Regset16(REG,16,true);
      delay(1000 / 2);

    }
     
  8. Максим B

    Максим B Гуру

    i &= ~(1 << 4); // Сброс 4-го бита в 0 а по пальцам если объяснить такую запись? Спасибо
     
  9. Unixon

    Unixon Оракул Модератор

    Код (Text):
    1         00000001
    1<<4      00010000
    ~(1<<4)   11101111
    i         xxxxxxxx
    i&~(1<<4) xxx0xxxx
     
    Максим B нравится это.
  10. Максим B

    Максим B Гуру

    Спасибо, а эта i& операция я так понимаю присваения 0 -я i ???
     
  11. geher

    geher Гуру

    & - это операция побитного "и". Т.е. берутся два числа-параметра, и бит за битом (первые биты параметров, потом вторые биты параметров и т.д.) производится вычисление такого вида:
    0&0 = 0
    0&1 = 0
    1&0 = 0
    1&1 = 1
    Результат операции над битами записывается в бит с тем же номером в числе-результате.
    Т.е. если оба бита в очередной позиции параметров единичные, то в ту же позицию результата попадет единичный бит. Иначе - нулевой.

    Отсюда и способ сброса одного бита в 0 - провести операцию & данного числа с другим числом, все биты которого 1 (в соответствии с правилом выполнения данной операции будут сохранены старые значения), кроме одного нулевого ( в резутате будет 0 в нужном бите).

    i&=выражение
    является сокращенной формой следующего:
    i=i&(выражение), т.е. вычисляется значение выражения, выполняется операция & между хначением i и результатом вычисления выражения, результат операции записывается в i, заменяя предыдущее значение.
     
    Максим B нравится это.
  12. Максим B

    Максим B Гуру

    Я реально с этими битовыми операциями просто плаваю, кучу литературы уже прочитал, а все равно не доходит ((( Спасибо Вам, за разъяснения.
     
  13. DrProg

    DrProg Вечный нерд

    А я предпочитаю c 595ми работать без SPI. Напрямую. Через тот же ShihtOut в конце концов, правда заменил его своим. Мне кажется так нагляднее, прозрачнее, быстрее и код короче. Например, на двухцветную матрицу на трех 595 UNO выдает около 2,5 тысяч кадров в секунду. Serial(9600) так сможет?
     
    ИгорьК нравится это.