Конфликт 2 устройств SPI
Я хочу подключить Ethernet-модуль W5500 и модуль SD-карты к Arduino Uno с помощью SPI (конечно, с разными контактами CS). При отдельном подключении они работают нормально, но при подключении в одну цепь модуль Ethernet не получает правильный IP-адрес и всегда получает адрес 255.255.255.255. Для меня модуль Ethernet является вероятным виновником, поскольку модуль SD-карты работает без проблем, даже когда модуль Ethernet также подключен.
Пытался использовать Ethernet & Библиотеки Ethernet2, но без разницы. Пробовал вручную назначать IP-адрес, но это не сработает. Я даже установил контакты CS в HIGH в настройке перед вызовом SD.begin & Ethernet.begin(), чтобы оба компонента не «прослушивали» одновременно, но это все равно не работает. Как это исправить?
Вот скетч, над которым я работаю. Хотя он не использует модуль SD, но, как упоминалось выше, если модуль SD подключен к цепи, модуль Ethernet не получает неверный IP-адрес
#include <SPI.h>
#include <Ethernet2.h>
//IP-адрес ip(192, 168, 1, 22);
// MAC-адрес просто должен быть уникальным. Это должно работать
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
EthernetServer server(80);
void setup()
{
pinMode(8, OUTPUT); // SD-модуль CS
digitalWrite(8, HIGH);
pinMode(10, OUTPUT); // Ethernet-модуль CS
digitalWrite(10, HIGH);
delay(1);
Serial.begin(9600);
Ethernet.begin(mac);
server.begin();
Serial.print("Server started on: ");
Serial.println(Ethernet.localIP());
}
void loop()
{
// прослушивание входящих клиентов
EthernetClient client = server.available();
if (client)
{
while (client.connected())
{
// отправляем стандартный HTTP-заголовок ответа
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html");
client.println();
// отправить тело
client.println("<html><body>");
client.println("<h1>Arduino Server</h1>");
client.print("<p>A0=");
client.print(analogRead(0));
client.println("</p>");
client.print("<p>millis=");
client.print(millis());
client.println("</p>");
client.println("</body></html>");
client.stop();
}
delay(1);
}
}
Еще один скетч со ссылкой на библиотеки SD и Ethernet
#include <SPI.h>
#include <Ethernet.h>
#include <SD.h>
byte mac[] = { 0x00, 0xC3, 0xA2, 0xE6, 0x3D, 0x57 };
byte LED = 2;
char wServer[] = "media.wizards.com";
char wFile[] = "/images/magic/tcg/resources/rules/MagicCompRules_20140601.pdf";
EthernetClient myClient;
void setup() {
//D53 на Arduino Mega должен быть выходом.
pinMode(53, OUTPUT);
pinMode(LED, OUTPUT);
Serial.begin(9600);
while (!Serial);
Serial.print("Establishing network connection... ");
if (Ethernet.begin(mac) == 0) {
Serial.println("FAILED!");
while (true) {
digitalWrite(LED, HIGH);
delay(500);
digitalWrite(LED, LOW);
delay(500);
}
}
else {
Serial.println("OK!");
}
}
void loop() {
Serial.print("Connecting to ");
Serial.print(wServer);
Serial.print("... ");
if (myClient.connect(wServer, 80) == 1) {
Serial.println("OK!");
myClient.print("GET ");
myClient.print(wFile);
myClient.println(" HTTP/1.0");
myClient.print("Host: ");
myClient.println(wServer);
myClient.println();
if (SD.begin(8)) {
if (SD.exists("MAGIC.PDF"))
SD.remove("MAGIC.PDF");
Serial.print("Saving response... ");
digitalWrite(LED, HIGH);
File dd = SD.open("MAGIC.PDF", FILE_WRITE);
char lc;
while (myClient.connected()) {
if (myClient.available()) {
char nc = myClient.read();
if ((lc == 10) && (nc == 13)) {
while (myClient.available() == 0);
myClient.read();
break;
}
else
lc = nc;
}
}
while (myClient.connected()) {
if (myClient.available() > 0) {
dd.write(myClient.read());
}
}
dd.close();
delay(500);
Serial.println("OK");
digitalWrite(LED, LOW);
}
else
Serial.println("No SD card detected!");
myClient.stop();
}
else
Serial.println("FAILED!");
delay(3600000);
asm volatile(" jmp 0");
@Zaffresky, 👍0
Обсуждение1 ответ
У меня была такая же проблема с модулем SD-карты.
Я не очень хорошо разбираюсь во всех деталях, но это связано с тем, что большинство модулей SD-карт (простых) не имеют функции трех состояний, то есть они не могут работать с несколькими устройствами SPI на одной шине.
К сожалению, у Arduino есть только одно соединение SPI, но есть решения:
- Существуют буферы с тремя состояниями, которые вы можете использовать (где-то в диапазоне CD или 74HC). См. комментарий hcheung: используйте, например, буфер с тремя состояниями 74AHC125 MISO.
- Однако другим решением является использование, например, защитного экрана SD-карты, например https://boutique.semageek.com/en/1445-sd-storage-shield-with-rtc-clock-for-arduino.html
Я думаю, вы имеете в виду [74AHC125](https://cdn-shop.adafruit.com/datasheets/74AHC125.pdf) для использования буфера с тремя состояниями MISO., @hcheung
@hcheung да, спасибо ... добавлю в ответ, @Michel Keijzers
Проблема с SD-картами заключается в том, что SD-карта не соответствует строго стандартам протокола SPI. Вывод CS не приводит к изоляции SD-карты от шины, как это должно быть, и есть определенные операции, которые вы выполняете с SD-картой через шину SPI, когда вывод CS удерживается в высоком состоянии., @Majenko
Также важен порядок инициализации. Вы должны запустить SD-карту перед любым другим устройством SPI, чтобы убедиться, что каждое устройство на шине является SPI, поскольку SD-карта по умолчанию работает в режиме SDIO, и это может мешать остальной части шины., @Majenko
@Majenko, прав ли я, что буфер с тремя состояниями, такой как 74AHC125, решит проблему с выводом CS?, @Michel Keijzers
Это, безусловно, помогает делу, да. Когда SD изолирован от шины, то, что бы он ни делал, он не может мешать остальной части шины., @Majenko
Лично я никогда не делю шину SPI с чем-либо еще при использовании SD-карты (но тогда я использую PIC32 с несколькими шинами SPI). При необходимости вы всегда можете использовать SPI для других устройств, которым не нужна высокая скорость., @Majenko
@Majenko приятно знать, спасибо ... давно не использовал SD-карту, но обнаружил проблему, когда начал работать с Arduino, честно говоря, никогда не пробовал буфер (так как я просто пробовал много вещей)., @Michel Keijzers
@Majenko Также одной из причин использования STM32 является то, что у них действительно больше функций (например, больше SPI и особенно больше SRAM)., @Michel Keijzers
@MichelKeijzers Мех ... если вам нравится ARM, конечно ... Дайте мне MIPS в любой день;), @Majenko
@Majenko, можете ли вы привести пример микроконтроллеров MIPS? (или я что-то пропустил), @Michel Keijzers
@MichelKeijzers PIC32. Это все, что я использую, если мне не нужно использовать что-то еще из-за требований клиента., @Majenko
@Majenko как-то это на самом деле не рекламируется или около того ... Я имею в виду, что я проверил Arduino и обнаружил, что он слишком ограничивает то, что я хотел (изучение микроконтроллеров), и наиболее «очевидные» ссылки, где STM32 (F1). Так что я не знаю, насколько хорош/плох PIC32 (вероятно, хорош, поскольку им пользуются профессионалы). Но я немного сомневаюсь, чтобы перейти (снова) на другую архитектуру., @Michel Keijzers
Хе. Преимущество PIC32 в том, что он получает от меня наилучшую аппаратную/программную поддержку;) chipKIT — это вариант API Arduino для PIC32, хотя он немного отстает по некоторым функциям API., @Majenko
@Majenko Я проверю это (потому что мне любопытно)., @Michel Keijzers
@MichelKeijzers Спасибо за информацию, но мне интересно, использует ли экран SD-карты также шину SPI? Если да, то чем он будет отличаться от использования модуля SD-карты?, @Zaffresky
@Majenko Я ничего не знаю об этом буфере с тремя состояниями, но прочитаю о нем больше. Также необходимо сначала заказать микросхему 74AHC125, чтобы протестировать ее., @Zaffresky
@Majenko Я пытался инициировать SD-карту до запуска Ethernet, но все равно не получается. Я предполагаю, что это скорее аппаратная проблема, и проблема с буфером с тремя состояниями, вероятно, исправит это. Что меня действительно удивляет, так это то, что даже если я подтяну CSpin SD-карты к высокому уровню на протяжении всего скетча, модуль Ethernet не сможет получить правильный IP-адрес, поэтому поддержание его CS-контакта на высоком уровне не имеет никакого эффекта?, @Zaffresky
- Простая веб-страница с Ethernet-шилдом Arduino на SD-карте
- Получить изображение с SD-карты Arduino Ethernet Shield
- SD-карта не инициализируется
- Что означают эти контакты? Куда мне их подключить?
- Клиент MQTT на Arduino + SIM900
- Удаленная загрузка кода на плату Arduino через интернет
- Понимание того, почему следует избегать «String» и альтернативных решений
- Arduino: как записать значение переменной в текстовый файл и изменить его на SD-карте?
Где вы сказали библиотеке SD и библиотеке Ethernet, какую CS они должны использовать?, @theSealion
В дополнение к @theSealion очень актуальный вопрос. Эта [статья](https://www.pjrc.com/better-spi-bus-design-in-3-steps/) должна помочь вам устранить неполадки и сузить круг причин., @hcheung
[ethernet2.h](https://github.com/adafruit/Ethernet2) устарел., @hcheung
ethernet2 по умолчанию использует контакт 10 в качестве cs (https://github.com/adafruit/Ethernet2/blob/master/src/utility/w5500.h#L133), однако ваш код не имеет ссылки на библиотеку SD-карт или инициализацию SD Card., @hcheung
Я экспериментировал с несколькими различными скетчами, но это не работает. Я загрузил другой скетч, который пробовал, но он не работает., @Zaffresky
@theSealion, библиотека Ethernet, по умолчанию использует контакт 10 в качестве cspin, поэтому нет необходимости упоминать об этом. Как я упоминал в своем исходном посте, сохранение в цепи как модуля SD-карты, так и модуля Ethernet вызывает проблему. Неважно, есть в скетче ссылка на библиотеку SD или нет. Поскольку в моей схеме модуль sd имеет контакт 8 как CSpin, и я поднял его, чтобы избежать конфликта, но это не помогает., @Zaffresky
@Zaffresky, чем я бы рекомендовал начать смотреть на оборудование. Возьмите вольтметр и посмотрите на линии CS и SPI, когда микроконтроллер находится в состоянии сброса и когда ваш скетч работает. Еще лучше было бы осциллографом смотреть сигнал., @theSealion