помогите разобраться с 74HC595 64бит

radiofannat
radiofannat аватар
Offline
Зарегистрирован: 11.09.2013

Здравствуйте, я в коде не очень разбираюсь, помогите с кодом.

задача такая, по сути это бегущий огонь, надо засунуть 64 бита в регистры 74HC595, но в переменную long можно только 32 бит засунуть, код взял здесь внизу http://arduino.ru/Tutorial/registr_74HC595

переделал немного под себя:

//Пин подключен к ST_CP (SS) входу 12 74HC595
const int ssPin = 38;
//Пин подключен к SH_CP (SCLK) входу 11 74HC595
const int sclkPin = 39;
//Пин подключен к DS (DATA) входу 14 74HC595
const int dataPin = 40;
 
char inputString[2];
 
void setup() {
   //устанавливаем режим OUTPUT
  pinMode(ssPin, OUTPUT);
  pinMode(dataPin, OUTPUT); 
  pinMode(sclkPin, OUTPUT);
  Serial.begin(9600);
  Serial.println("reset");
}
 
void loop() {
  for (int thisLed = 3; thisLed < 47; thisLed++) 
  {
    registerWrite(thisLed, HIGH);
    delay(30);
    if (thisLed > 0) {
      registerWrite(thisLed - 1, LOW);
    }
    else {
      registerWrite(47, LOW);
    }
  }
 
}
 
// этот метод отсылает бит на сдвиговый регистр
 
void registerWrite(int whichPin, int whichState) {
  // для хранения 32 битов используем unsigned int

  long bitsToSend = 0;   //вот здесь оганичение 32 бит

  // выключаем светодиоды на время передачи битов
  digitalWrite(ssPin, LOW);
 
  // устанавливаем HIGH в соответствующий бит
  bitWrite(bitsToSend, whichPin, whichState);

  // здвигаем 48 бит
  // для записи в 1-6 регистр
  byte register1 = (bitsToSend) >> 40;
  byte register2 = (bitsToSend) >> 32;
  byte register3 = (bitsToSend) >> 24;
  byte register4 = (bitsToSend) >> 16;
  byte register5 = (bitsToSend) >> 8;
  byte register6 = (bitsToSend);
 
  // "проталкиваем" байты в регистры
  shiftOut(dataPin, sclkPin, MSBFIRST, register1);
  shiftOut(dataPin, sclkPin, MSBFIRST, register2);
  shiftOut(dataPin, sclkPin, MSBFIRST, register3);
  shiftOut(dataPin, sclkPin, MSBFIRST, register4);
  shiftOut(dataPin, sclkPin, MSBFIRST, register5);
  shiftOut(dataPin, sclkPin, MSBFIRST, register6);
 
  // "защелкиваем" регистр, чтобы биты появились на выходах регистра
  digitalWrite(ssPin, HIGH);
}

я думаю что этот код не идеален, может как то проще его сделать?

axill
Offline
Зарегистрирован: 05.09.2011

Самый простой вариант будет если вы можете регистры подключить к железному SPI

Тогда запись 64 бит будет как запись 4-х байт и в конце подать положительный импульс на latch входы для защелкивантя - итого 6 строк кода

radiofannat
radiofannat аватар
Offline
Зарегистрирован: 11.09.2013

здесь я совсем в тупике, проверял некоторые устройства на SPI -работают, а вот регистры сдвига не захотели работать, даже не знаю в чём проблема! по спецификации мега 1280 подключена к 595 правильно, компилятор не ругается, НО НЕ РАБОТАЕТ! как будто выводы в воздухе...

по этому и решил програмно.

------

только что попробовал по SPI всё работает! но всё же интересует именно програмный метод, помогите разобраться!

radiofannat
radiofannat аватар
Offline
Зарегистрирован: 11.09.2013

неужели никто не хочет мне помочь? где Вы програмисты?!

maksim
Offline
Зарегистрирован: 12.02.2012
#define SSpin   38  // Пин подключен к ST_CP (SS) входу 12 74HC595
#define SCLKpin 39  // Пин подключен к SH_CP (SCLK) входу 11 74HC595
#define DATApin 40 // Пин подключен к DS (DATA) входу 14 74HC595*/

void setup() 
{
  //устанавливаем режим OUTPUT
  pinMode(SSpin, OUTPUT);
  pinMode(DATApin, OUTPUT); 
  pinMode(SCLKpin, OUTPUT);
  Serial.begin(9600);
  Serial.println("reset");
}

void loop() 
{
  for(char thisLed = 1; thisLed < 64; thisLed++) 
  {
    registerWrite(thisLed, 1);
    registerWrite(thisLed-1, 0);
    delay(30);
  }
}

void registerWrite(byte whichPin, bool whichState) 
{
  static uint64_t bitsToSend = 0;
  if(whichState) bitsToSend |= 1LL<<whichPin;
  else bitsToSend &= ~(1LL<<whichPin);
  
  digitalWrite(SSpin, LOW);
  for(byte i = 0; i < 64; i++) // "проталкиваем" байты в регистры
  {
    digitalWrite(SCLKpin, 0);
    if((1LL<<i)&bitsToSend) digitalWrite(DATApin, 1);
    else digitalWrite(DATApin, 0);
    digitalWrite(SCLKpin, 1);
  }
  digitalWrite(SSpin, HIGH);
}

 

radiofannat
radiofannat аватар
Offline
Зарегистрирован: 11.09.2013

спасибо, код рабочий, только что проверил)

есть вопросы по этому коду, какую функцию выполняет код ниже

static uint64_t bitsToSend = 0; //это как я понимаю обьявляется статическая переменная uint64_t размером 8байт?
if(whichState) bitsToSend |= 1LL<<whichPin; // и дальше немного запутался поясните
else bitsToSend &= ~(1LL<<whichPin);

ещё раз спасибо за код!!!

MYFRIEND
MYFRIEND аватар
Offline
Зарегистрирован: 31.01.2017

ДД! всем. Подскажите, как отдельно каждый светодиод нажать из 210 шт. нужно, протолкнуть хорошо, где формировать то что нужно протолкнуть,  с одним регистром все понятно, а нужно 64 бит или 128 бит, в нашем случае для 210 шт. светодиодов нужно 210 бит. Помогите чайнику.