SPI: Sram + сдвиговый регистр

matmotex
matmotex аватар
Offline
Зарегистрирован: 01.05.2022
Привет!)
И так, в моей жизни наступил такой момент, когда стало жизненно необходимо использовать связку atmega + 23LCV512 (она же SRAM, версия на 64 кб) + SN74HC165N (сдвиговый регистр дающий на вход + 8 пинов).
Столкнулся с такой проблемой: при подключении сразу двух этих устройств к одной шине SPI я теряю возможность работать co SRAM модулем.
 
Проблема вылезла при попытке внедрить ее в уже работающий большой проект, но чтобы не вываливать сюда огромную кучу незаконченных схем я вытащил проблему в небольшую схему и повторил ее.
 
Далее привожу две схемы:
P.S.: на схеме изображен hc595, но на самом деле я использую hc165, просто не нашел нужный компонент:)
 
Красный - плюс
Черный - масса
Оранжевый - SPI clock
Фиолетовый - MISO
Синий MOSI
Желтый - CE для 23LC (SRAM)
Зеленый - CE для 74HC165
Голубой - PL для 74HC165, она же защелка для перехвата состояния портов ввода микросхемы.
 
Работает:
 
Не работает:

 

Проблема выглядит таким образом:

При подключении одной лишь 23LC я могу свободно работать с памятью на запись и чтение.
Если в схеме появляется 74HC165, я эту возможность теряю, однако работать со сдвиговым регистром могу. При попытке прочитать память получаю сплошные нули.
Если у регистра отключить ногу MISO, возможность возвращается.
Выглядит так, будто CE у регистра игнорирует логическую единицу, хотя она точно подается.
//-------------MEMORY------------------
#define MEMORY_RDSR        5
#define MEMORY_WRSR        1
#define MEMORY_READ        3
#define MEMORY_WRITE       2

#include "SPI.h"

int pinPL = 5;
int pinCE = 4;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);

  //Инициализирую SPI
  SPI.begin();
  SPI.setClockDivider(SPI_CLOCK_DIV4);
  SPI.setDataMode(SPI_MODE0);
  SPI.setBitOrder(MSBFIRST);

  //Готовлю к работе память
  memoryInit();

  //Готовлю к работе регистр
  pinMode(pinPL, OUTPUT);
  pinMode(pinCE, OUTPUT);
  digitalWrite(pinPL, HIGH);
  digitalWrite(pinCE, HIGH);
  delay(1000);

  //Операции ввода вывода в цикле при старте
  for (uint8_t i=0; i<32; i++)
  {
    memoryWriteByte(0, i);
    uint8_t value = memoryReadByte(0);
    Serial.println(value);
    
  }
}

void loop() {
  // put your main code here, to run repeatedly:
  delay (1000);


  //Перехватываю состояние портов ввода у регистра
  digitalWrite(pinPL, LOW);
  delay(5);
  digitalWrite(pinPL, HIGH);

  //Получаю данные с регистра
  digitalWrite(pinCE, LOW);
  uint8_t value = SPI.transfer(0);
  digitalWrite(pinCE, LOW);

  Serial.println(value);
}


void memoryInit()
{
  pinMode(6, OUTPUT);
  memoryClose();
}


void memoryOpen()
{
  digitalWrite(6, LOW);
  delay(5);
}


void memoryClose()
{
  digitalWrite(6, HIGH);
  delay(5);
}


void memoryWriteByte(uint32_t address, uint8_t data_byte)
{
  memoryOpen();
  SPI.transfer(MEMORY_WRITE);
  SPI.transfer((uint8_t)(address >> 16) & 0xff);
  SPI.transfer((uint8_t)(address >> 8) & 0xff);
  SPI.transfer((uint8_t)address);
  SPI.transfer(data_byte);
  memoryClose();
}


uint8_t memoryReadByte(uint32_t address)
{
  memoryOpen();
  SPI.transfer(MEMORY_READ);
  SPI.transfer((uint8_t)(address >> 16) & 0xff);
  SPI.transfer((uint8_t)(address >> 8) & 0xff);
  SPI.transfer((uint8_t)address);
  uint8_t result = SPI.transfer(0x00);
  memoryClose();
  return result;
}

Так же снял на видео демонстрацию самой проблемы: https://www.youtube.com/watch?v=V2C3figf3LM

Джентльмены, с этой проблемой я столкнулся еще пол года назад, и до сих пор ее не решил. Уже и не помню как пробовал ее решить. Я правда заинтересован в решении этой проблемы! :)

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

 

 

xDriver
xDriver аватар
Offline
Зарегистрирован: 14.08.2015

matmotex пишет:

Выглядит так, будто CE у регистра игнорирует логическую единицу, хотя она точно подается.
 
это какой вывод СЕ у регистра? номер?
xDriver
xDriver аватар
Offline
Зарегистрирован: 14.08.2015

и так в догонку,как думаете какие состояния могут быть на выводах 7,9 (Q ^Q)?

matmotex
matmotex аватар
Offline
Зарегистрирован: 01.05.2022

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

xDriver
xDriver аватар
Offline
Зарегистрирован: 14.08.2015

matmotex пишет:

Однако при логическом нуле открывается тактирование, при логической единице тактирование закрывается.

вот именно, когда нет тактирования, что на 9 и 7 пине? подумайте.

xDriver
xDriver аватар
Offline
Зарегистрирован: 14.08.2015

ладно не буду мучать

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

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

matmotex
matmotex аватар
Offline
Зарегистрирован: 01.05.2022

В силу своей глупости схематически объяснить не смогу. Однако смею предположить, что на 9 будет логический ноль, а на 7 логическая единица.
Правильно ли я понял:
- мне нужно обеспечить разрыв регистра от MISO когда регистр не используется?
Возможно имеет смысл отдать регистру программный SPI на атмеге?

xDriver
xDriver аватар
Offline
Зарегистрирован: 14.08.2015

matmotex пишет:

Правильно ли я понял:
- мне нужно обеспечить разрыв регистра от MISO когда регистр не используется?
Возможно имеет смысл отдать регистру программный SPI на атмеге?

да

я предпочитаю "железные" решения, но это тоже имеет право на существование.

matmotex
matmotex аватар
Offline
Зарегистрирован: 01.05.2022

Благодарю за помощь и направление. Буду разбираться в этом моменте более детально :)

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Я в подобном случае подключал к выходу данных регистра [последовательно] резистор 1-2 кОм. 

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