ЭЛЕКТРОНИКА SPI: Sram + сдвиговый регистр

matmotex

✩✩✩✩✩✩✩
14 Июл 2022
2
0
32
Привет!)
И так, в моей жизни наступил такой момент, когда стало жизненно необходимо использовать связку atmega + 23LCV512 (она же SRAM, версия на 64 кб) + SN74HC165N (сдвиговый регистр дающий на вход + 8 пинов).
Столкнулся с такой проблемой: при подключении сразу двух этих устройств к одной шине SPI я теряю возможность работать co SRAM модулем.

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

Далее привожу две схемы:
P.S.: на схеме изображен hc595, но на самом деле я использую hc165, просто не нашел нужный компонент:)

Красный - плюс
Черный - масса
Оранжевый - SPI clock
Фиолетовый - MISO
Синий MOSI
Желтый - CE для 23LC (SRAM)
Зеленый - CE для 74HC165
Голубой - PL для 74HC165, она же защелка для перехвата состояния портов ввода микросхемы.

Работает:
test1.jpg

Не работает:
test2.jpg

Проблема выглядит таким образом:
При подключении одной лишь 23LC я могу свободно работать с памятью на запись и чтение.
Если в схеме появляется 74HC165, я эту возможность теряю, однако работать со сдвиговым регистром могу. При попытке прочитать память получаю сплошные нули.
Если у регистра отключить ногу MISO, возможность возвращается.
Выглядит так, будто CE у регистра игнорирует логическую единицу, хотя она точно подается.

Код:
C++:
//-------------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;
}

Так же снял на видео демонстрацию самой проблемы:

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

Буду благодарен каждому при любой попытке помочь.
 

Старик Похабыч

★★★★★★★
14 Авг 2019
4,222
1,291
Москва
Я как то подключал 8 дисплеев 12864 SPI к одному модулю ESP32 , так вот теоретически это все работало, но периодически на отключенных по CS дисплеях выпадал мусор. Пока не собрал все на мультипексорах четкой работы не получил - пробовал разное, и хитрые подтяжки , и схемы разные. На 2-3 еще работало без сбоев, а вот 8 уже никак.
Вот тут схема на 2 штуки:
 

bort707

★★★★★★✩
21 Сен 2020
3,003
898
@Старик Похабыч, ссылка нормально не работает, вылезает какой-то поиск и потом экран заполняется кучей совершенно левых проектов.

Могу только предполагать что за мультиплексоры там по ссылке, но по сути вопроса ТС - его проблема легко решается с использованием переключателя шины типа hst3125
 

matmotex

✩✩✩✩✩✩✩
14 Июл 2022
2
0
32
@bort707, боюсь в таком случае я могу проиграть по быстродействию.
@Старик Похабыч, я попробую изучу устройство работы данного дисплейного модуля, и попробую понять, что происходит на схеме.

В любом случае в изначальном проекте уже работает несколько SPI девайсов. Но проблема только вот с этими двумя, и только они работают в MISO. Остальные в MOSI, и с ними проблем нет.