SPI: Sram + сдвиговый регистр
- Войдите на сайт для отправки комментариев
Чт, 14/07/2022 - 16:15
Привет!)
И так, в моей жизни наступил такой момент, когда стало жизненно необходимо использовать связку 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
Джентльмены, с этой проблемой я столкнулся еще пол года назад, и до сих пор ее не решил. Уже и не помню как пробовал ее решить. Я правда заинтересован в решении этой проблемы! :)
Оговорюсь сразу, в схемотехнике я хоть и не первый день, но я не специалист, и даже не любитель.
Буду благодарен каждому при любой попытке помочь.
и так в догонку,как думаете какие состояния могут быть на выводах 7,9 (Q ^Q)?
Взято из интернета.
В целом на изображениях самой схемы я указал)
Разумеется, я понимаю что не совсем правильно называть пины регистра так же, как они называются в SPI, ведь это совсем не SPI девайс.
Однако при логическом нуле открывается тактирование, при логической единице тактирование закрывается.
Однако при логическом нуле открывается тактирование, при логической единице тактирование закрывается.
вот именно, когда нет тактирования, что на 9 и 7 пине? подумайте.
ладно не буду мучать
там либо ноль, либо единица, которые мешают работать вашей памяти, а точнее спай протоколу потому что ножка мисо также либо в нуле, либо в единице
вам нужен буфер на выходе способны принимать третье состояние (Z), вот им и будете отключать регистр от шины спай.
В силу своей глупости схематически объяснить не смогу. Однако смею предположить, что на 9 будет логический ноль, а на 7 логическая единица.
Правильно ли я понял:
- мне нужно обеспечить разрыв регистра от MISO когда регистр не используется?
Возможно имеет смысл отдать регистру программный SPI на атмеге?
Правильно ли я понял:
- мне нужно обеспечить разрыв регистра от MISO когда регистр не используется?
Возможно имеет смысл отдать регистру программный SPI на атмеге?
да
я предпочитаю "железные" решения, но это тоже имеет право на существование.
Благодарю за помощь и направление. Буду разбираться в этом моменте более детально :)
Я в подобном случае подключал к выходу данных регистра [последовательно] резистор 1-2 кОм.
Когда второе устройство отключено от шины, регистр спокойно работает через резистор. А как только к шине подключается другое устройство, оно и задает нужный уровень, а регистр через резистор уже ничего сделать не может.