SPI datos recibidos incorrectos

Estoy tratando de ejecutar el ejemplo SPI de STM32Cube usando una placa STM32F429 y una placa STM32F4. El primero tiene 180 MHz de reloj y el segundo 168 MHz, ambos con microcontroladores Arm cortex-M3 similares.

Estoy usando la biblioteca HAL para acceder a los periféricos y la estoy configurando con esto:

principal.c ==>

  SpiHandle.Instance               = SPI4;
  SpiHandle.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_64;
  SpiHandle.Init.Direction         = SPI_DIRECTION_2LINES;
  SpiHandle.Init.CLKPhase          = SPI_PHASE_1EDGE;
  SpiHandle.Init.CLKPolarity       = SPI_POLARITY_HIGH;
  SpiHandle.Init.CRCCalculation    = SPI_CRCCALCULATION_DISABLE;
  SpiHandle.Init.CRCPolynomial     = 7;
  SpiHandle.Init.DataSize          = SPI_DATASIZE_8BIT;
  SpiHandle.Init.FirstBit          = SPI_FIRSTBIT_MSB;
  SpiHandle.Init.NSS               = SPI_NSS_SOFT;
  SpiHandle.Init.TIMode            = SPI_TIMODE_DISABLE;
  if(HAL_SPI_Init(&SpiHandle) != HAL_OK)
  {
    /* Initialization Error */
    Error_Handler();
  }

stm32f4xx_hal_msp.c ==>

void HAL_SPI_MspInit(SPI_HandleTypeDef *hspi)
{
  GPIO_InitTypeDef  GPIO_InitStruct;

  /*##-1- Enable peripherals and GPIO Clocks #################################*/
  /* Enable GPIO TX/RX clock */
  SPIx_SCK_GPIO_CLK_ENABLE();
  SPIx_MISO_GPIO_CLK_ENABLE();
  SPIx_MOSI_GPIO_CLK_ENABLE();
  /* Enable SPI clock */
  SPIx_CLK_ENABLE(); 

  /*##-2- Configure peripheral GPIO ##########################################*/  
  /* SPI SCK GPIO pin configuration  */
  GPIO_InitStruct.Pin       = SPIx_SCK_PIN;
  GPIO_InitStruct.Mode      = GPIO_MODE_AF_PP;
  GPIO_InitStruct.Pull      = GPIO_PULLUP;
  GPIO_InitStruct.Speed     = GPIO_SPEED_LOW;
  GPIO_InitStruct.Alternate = SPIx_SCK_AF;

  HAL_GPIO_Init(SPIx_SCK_GPIO_PORT, &GPIO_InitStruct);

  /* SPI MISO GPIO pin configuration  */
  GPIO_InitStruct.Pin = SPIx_MISO_PIN;
  GPIO_InitStruct.Alternate = SPIx_MISO_AF;

  HAL_GPIO_Init(SPIx_MISO_GPIO_PORT, &GPIO_InitStruct);

  /* SPI MOSI GPIO pin configuration  */
  GPIO_InitStruct.Pin = SPIx_MOSI_PIN;
  GPIO_InitStruct.Alternate = SPIx_MOSI_AF;

  HAL_GPIO_Init(SPIx_MOSI_GPIO_PORT, &GPIO_InitStruct);

  /*##-3- Configure the NVIC for SPI #########################################*/
  /* NVIC for SPI */
  HAL_NVIC_SetPriority(SPIx_IRQn, 0, 1);
  HAL_NVIC_EnableIRQ(SPIx_IRQn);
}

Tanto el maestro como el esclavo tienen la misma configuración. El problema es que el esclavo recibe los datos correctamente pero el maestro tiene un tiempo de operación en el último bit de cada byte. Por ejemplo, envié {0x01, 0x00, 0x00}y el maestro recibió {0x00, 0x01, 0x00}. Me parece que está haciendo una operación OR con el último bit o simplemente sustituyéndolo por el último bit del último byte recibido.

¡Gracias!

Respuestas (2)

Es posible que el problema esté en el código de la aplicación y no en las rutinas de inicialización.

Generalmente, el dispositivo maestro enviará un comando al esclavo solicitando información. Luego, el maestro proporciona suficientes pulsos de reloj para que el esclavo responda con los datos solicitados.

El problema es que el maestro está enviando y recibiendo al mismo tiempo. Mientras el mensaje de comando sale del registro TX, el registro RX también se llena. Pero el esclavo aún no envía nada porque todavía recibe el comando. El resultado final es que el maestro ahora tiene un byte en su búfer RX que debe descartarse. Este valor es generalmente {0x00} o {0xFF} dependiendo del estado inactivo de la línea MISO.

Para descartar el byte en el STM32, debe leer el Registro de datos. Espero que use SPI_I2S_ReceiveData() o algo similar.

Después de que se envía el comando (y se borra el registro RX), el maestro envía "bytes ficticios" para que cree pulsos de reloj para el esclavo. Esto generalmente puede ser cualquier valor, pero depende del esclavo.

Intenta enviar {0x01, 0x02, 0x03}. Si el maestro recibe {0x00, 0x01, 0x02}, debe modificar su código de controlador para descartar el primer byte.

Aparentemente, el problema era que el suelo no estaba conectado. ¡Qué vergüenza, lo siento!

¡Ja! Eso me ha pasado muchas veces :) Gracias por avisarnos. Dejo mi respuesta por si le sirve a alguien...