Подключил две микросхемы одному гайду , все работает с помощью скетча от туда же. однако мне такой метод вообше не нравится поэтому написал немного другой. с одной микросхемой работает , но стоит подключить вторую первая группа светодиодов работает нормально , а вот вторая начинает ели мелькать и сразу гаснуть. Вот так подключил: вот скетч, написанный мной Код (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); } Может кто нибудь помочь с этой микросхемой?
Навскидку.... В схеме не вижу подключения "земли" (вывод 8 микросхем). Микросхемы "не связаны" через пин 9 -- светодиоды на обоих микросхемах должны гореть одинаково. C SPI на практике пока не связывался, но судя по тому, что знаю, в Arduino UNO интерфейс SPI использует пины 11, 12, 13, 10 (https://www.arduino.cc/en/Reference/SPI). Вы же в схеме используете пин 2.
по началу я подключал к 8 пину землю однако потом заметил что сверху тоже можно подать землю. судя по гайду если связать 9(1) и 14(2) пины на микросхемах то они должны стать кластером. SPI подключен правильно , 2 пин это "защелка" , выбор устройства для управления.
Как и где заметили? Если по поводу пина 13 (!OE) микросхем (в Вашей схеме он подключен на землю), то он отвечает за активацию выходов, и к "земле" отношения не имеет. На "землю" этот пин подключается для активации выходов. Подключите 8-й пин микросхем к "земле". Хоть это и противоречит ссылке, приведенной мной в предыдущем посте, спорить не буду, т.к. на практике не сталкивался, только в теории.
Я это заметил случайно не подключив нижний ряд питания , но светодиоды работали . поэтому и решил что можно от туда дать землю.
Да еще со скетчем не много "перемудрили". Почему бы не взять, например, два 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
Спасибо! с помощью более продвинутых методов , массив регистров стал работать правильно Код (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); }
& - это операция побитного "и". Т.е. берутся два числа-параметра, и бит за битом (первые биты параметров, потом вторые биты параметров и т.д.) производится вычисление такого вида: 0&0 = 0 0&1 = 0 1&0 = 0 1&1 = 1 Результат операции над битами записывается в бит с тем же номером в числе-результате. Т.е. если оба бита в очередной позиции параметров единичные, то в ту же позицию результата попадет единичный бит. Иначе - нулевой. Отсюда и способ сброса одного бита в 0 - провести операцию & данного числа с другим числом, все биты которого 1 (в соответствии с правилом выполнения данной операции будут сохранены старые значения), кроме одного нулевого ( в резутате будет 0 в нужном бите). i&=выражение является сокращенной формой следующего: i=i&(выражение), т.е. вычисляется значение выражения, выполняется операция & между хначением i и результатом вычисления выражения, результат операции записывается в i, заменяя предыдущее значение.
Я реально с этими битовыми операциями просто плаваю, кучу литературы уже прочитал, а все равно не доходит ((( Спасибо Вам, за разъяснения.
А я предпочитаю c 595ми работать без SPI. Напрямую. Через тот же ShihtOut в конце концов, правда заменил его своим. Мне кажется так нагляднее, прозрачнее, быстрее и код короче. Например, на двухцветную матрицу на трех 595 UNO выдает около 2,5 тысяч кадров в секунду. Serial(9600) так сможет?