No obteniendo respuesta de MCP2515 usando SPI

4

Tengo una placa con una interfaz SPI que funciona. Puedo leer un esclavo a través de la interfaz SPI con éxito.

Cuando intento leer datos u obtener un estado en un esclavo secundario, MCP2515 IC, no estoy recibiendo ninguna respuesta. He verificado las conexiones mediante una prueba de continuidad del voltímetro, he verificado las conexiones de tierra y voltaje al IC. Entiendo que el MCP2515 es único en la forma en que se inicializa en el inicio según la hoja de datos. He intentado numerosas secuencias de inicialización sin éxito. Estoy empezando a pensar que tengo un mal IC, pero me gustaría poder probarlo y probar esa teoría.

El único otro problema que se me ocurre es un posible problema de sincronización. Tengo un cristal de 16 MHz en la MCU y un cristal de 16 MHz en el MCP2515 según la hoja de datos. Ambos tienen capacitores de 22 pF. Si el reloj está apagado, creo que al menos obtendría basura. ¿Alguien puede mirar el código y validarlo para que se vea bien y de hecho tengo un problema de reloj o hardware?

bool mcp2515_init(void)
{
    char str[80];
    unsigned int test_value;

    SET(MCP2515_CS);
    SET_OUTPUT(MCP2515_CS);

    SET(USB_CS);
    //SET_OUTPUT(USB_CS);

    SET(SD_CS);
    //SET_OUTPUT(SD_CS);

    RESET(P_SCK);
    RESET(P_MOSI);
    RESET(P_MISO);

    SET_OUTPUT(P_SCK);
    SET_OUTPUT(P_MOSI);
    SET_INPUT(P_MISO);

    SET_INPUT(MCP2515_INT);
    SET(MCP2515_INT);

    // Active SPI master interface
    SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0);
    SPSR = 0;

    // Reset MCP2515 by software reset.
    // After this it is in configuration mode.
    RESET(MCP2515_CS);
    spi_putc(SPI_RESET);
    SET(MCP2515_CS);

    // Wait a little bit until the MCP2515 has restarted
    _delay_us(15);

    // Load CNF1..3 Register
    RESET(MCP2515_CS);

    spi_putc(SPI_WRITE);
    spi_putc(CNF3);

    spi_putc((1<<PHSEG21));  // Bitrate 125 kbps at 16 MHz
    spi_putc((1<<BTLMODE)|(1<<PHSEG11));
    spi_putc((1<<BRP2)|(1<<BRP1)|(1<<BRP0));



    // Activate interrupts
    spi_putc((1<<RX1IE)|(1<<RX0IE));
    SET(MCP2515_CS);


    test_value = mcp2515_read_register(CANCTRL);
    sprintf(str, "test value is [%d]\n\n",test_value);
    UART1_TxString(str);

    // Test if we could read back the value => is the chip accessible?
    if (mcp2515_read_register(CNF1) != ((1<<BRP2)|(1<<BRP1)|(1<<BRP0))) {

        return false;
    }

    // Deactivate the RXnBF pins (high impedance state)
    mcp2515_write_register(BFPCTRL, 0);

    // Set TXnRTS as inputs
    mcp2515_write_register(TXRTSCTRL, 0);

    // Turn off filters => receive any message
    mcp2515_write_register(RXB0CTRL, (1<<RXM1)|(1<<RXM0));
    mcp2515_write_register(RXB1CTRL, (1<<RXM1)|(1<<RXM0));

    // Reset device to normal mode
    mcp2515_write_register(CANCTRL, 0);

    return true;
}
    
pregunta Eddie

2 respuestas

4

Después de muchas horas de depurar y probar el circuito, finalmente encontré que el problema estaba relacionado con el PIN RESTABLECIMIENTO en el MCP2515. Entendí mal la hoja de datos pensando que el PIN de RESET podría estar flotando y que podría usar el software RESET en su lugar. Ese no es el caso. El PIN de RESTABLECIMIENTO debe terminarse con una resistencia de extracción O atado al circuito de RESTABLECIMIENTO de su MCU. Elegí la opción de resistencia PULL-UP. Esto evita que el MCP2515 se atasque / cuelgue en el modo RESET. Después de agregar el pull-up al circuito, ahora puedo comunicarme con el MCP2515. Sería bueno si la hoja de datos tuviera una sección de "PINS mínimos requeridos" como lo tienen algunas hojas de datos. Espero que esto ayude a alguien más asegurándose de que todos los PINS requeridos se terminen antes de codificar :)

    
respondido por el Eddie
2

MCP2515 es un controlador CAN completo. SPI es la única manera de comunicarse con él.

Antes de preocuparse por el SPI, debe verificar si el chip tiene potencia y tierra; luego, si se suelta su pin de reinicio (es una buena idea controlar su pin de reinicio, para que pueda reiniciar el chip de manera confiable en cualquier momento); debe asegurarse de que su pin CS Chip Select esté seleccionado.

Incluso después de seleccionar y reiniciar el chip, la documentación le advierte que el controlador necesita algún tiempo para realizar su inicialización interna. Por ejemplo, uso 2msec delay después de reiniciarlo antes de intentar comunicarme con el chip.

Una vez que todo esté bien, tienes otra cosa extremadamente importante que hacer: ¡asegúrate de que la configuración SPI de tu procesador sea correcta! Usted menciona, su SPI ya está trabajando con otro chip. Eso no es suficiente, a menos que el otro chip use exactamente la misma configuración SPI, que le estoy dando un 25% de probabilidad: debe seleccionar la polaridad del reloj SPI (configure los datos en la CPU y los datos se registrarán en MCP2515 en el borde ascendente de SCK), el valor '0' es con línea en el nivel bajo.

Es absolutamente necesario estudiar la documentación del chip, parte 12.0 INTERFAZ SPI.

Una cosa más, hay una forma de bajo presupuesto para monitorear la línea si no tiene un osciloscopio, usa un voltímetro o un LED mejor conectado al pin monitoreado (use 3 LED: uno para reloj, SI y SO).

A continuación, lleve el software de su CPU al modo de depuración, y toque la comunicación SPI para verificar que el bus funciona. (Bit-bang significa establecer manualmente los pines del puerto en alto y bajo, mientras está avanzando a través del código).

Si bien eso es posible, no es la mejor práctica, porque le llevará tiempo, pero se realiza en muchas situaciones, incluso por profesionales. Si no desea comprar un osciloscopio, considere comprar una de esas cajas de analizadores lógicos con bajo nivel de USB, ¡muchos de ellos vienen con el software del analizador SPI incluido!

    
respondido por el EmbeddedGuy

Lea otras preguntas en las etiquetas