Конфликт SPI с двумя экранами - IOREF?

Обновление:

Я переработал код, чтобы сделать его более устойчивым к отсутствию плат или невозможности с ними общаться. Затем я возился с кучей контактов и узнал, что все сводится к тому, подключен ли контакт IOREF к USB Host Shield или нет. Если он подключен, USB-шилд «берет верх», разрешает связь с ним, но CAN-шилд не работает. Если контакт IOREF USB-шилда не подключен, а остальные контакты шилда подключены, CAN работает. Если я отключу контакт IOREF, идущий к экрану CAN (и, следовательно, экран USB также, поскольку он находится сверху), экран CAN по-прежнему работает нормально, но экран USB не работает.

Что-то происходит, когда IOREF подключен к плате USB, и если он не запитан, вы не можете с ним разговаривать.

Исходное сообщение:

У меня следующие настройки:

  1. Ваша плата RoboRED
  2. Seeed CAN Bus Shield v1.2 http://wiki.seeed.cc/CAN-BUS_Shield_V1.2/
  3. USB Host Shield https://www.arduino.cc/en/Main/ArduinoUSBHostShield

Моя проблема заключается в том, что если я подключаю только экран шины CAN, я могу инициализировать его без каких-либо проблем, но когда я подключаю хост-модуль USB поверх CAN, экран CAN перестает отвечать на запросы.

Я изучил проводку и, согласно спецификациям, аппаратное обеспечение настроено следующим образом:

  • Шина SPI работает с заголовком ICSP для обоих экранов, но не для D11, D12 и т.д. Д13. Я мог бы переключить его на экран CAN-шины, если бы захотел/необходимо было, но не думаю, что должен.
  • Триггерный контакт USB-хоста — D10.
  • Триггерный контакт для шины CAN — D9 (так как это версия 1.2 платы)
  • Обе платы имеют питание. Плата USB находится сверху, так как на ней нет штыревого разъема ICSP, а только гнездо снизу.

Я начал отлаживать код и проследил до этой функции шины CAN в mcp_can.cpp, которую я оснастил отладкой:

INT8U MCP_CAN::mcp2515_setCANCTRL_Mode(const INT8U newmode)
{
    Serial.print("mcp2515_setCANCTRL_Mode with newmode = ");
    Serial.println(newmode);
    INT8U i;

    mcp2515_modifyRegister(MCP_CANCTRL, MODE_MASK, newmode);

    i = mcp2515_readRegister(MCP_CANCTRL);
    i &= MODE_MASK;
    Serial.println("i & MODE_MASK");
    Serial.println(i);
    Serial.println(MODE_MASK);

    if ( i == newmode ) 
    {
        return MCP2515_OK;
    }

    return MCP2515_FAIL;
}

Вывод в случае сбоя:

USB started ok
past SPI begin
mcp2515_init called
mcp2515_setCANCTRL_Mode with newmode = 128
i & MODE_MASK
0
224
Enter setting mode fall
res = 1

Для справки, это функция mcp2515_modifyRegister:

void MCP_CAN::mcp2515_modifyRegister(const INT8U address, const INT8U mask, const INT8U data)
{
    #ifdef SPI_HAS_TRANSACTION
        SPI_BEGIN();
    #endif
    MCP2515_SELECT();
    spi_readwrite(MCP_BITMOD);
    spi_readwrite(address);
    spi_readwrite(mask);
    spi_readwrite(data);
    MCP2515_UNSELECT();
    #ifdef SPI_HAS_TRANSACTION
        SPI_END();
    #endif
}

Весь файл находится здесь: https://github.com/Seeed-Studio/CAN_BUS_Shield. /blob/master/mcp_can.cpp. Я попытался установить для SPI_HAS_TRANSACTION значение true без каких-либо изменений в результате, хотя я также не знаю точно, что это делает.

Это моя инициализация:

void setup (void)
{
    Serial.begin(115200);

    // init can bus: скорость = 500k

    if (Usb.Init() == -1)
        Serial.println("OSC did not start.");
    else
        Serial.println("USB started ok");

    delay( 200 );

    while (CAN_OK != CAN.begin(CAN_500KBPS)) {
        Serial.println("CAN BUS Shield init fail");
        Serial.println(" Init CAN BUS Shield again");
        delay(10000);
    }

    Serial.println("CANbus ready");
}

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

, 👍0


1 ответ


1

Между этими двумя платами существует аппаратный конфликт, который кажется неразрешимым. Решение состояло в том, чтобы купить USB-шилд Keyes, убедиться, что только он имеет доступ к контактам 9 и 10 от Arduino, а затем подключить контакт 7 (или 8) к контакту 9 шилда CAN, а также правильно инициализировать шилд CAN этим новый значок.

Наконец, ICSP-разъем Keyes USB Shield недостаточно длинный, поэтому вам нужно отрезать 2 мм штыревых контактов, отличных от ICSP, чтобы правильно разместить его на CAN-шилде.

,