SPI mal recibido datos

0

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

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

main.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 algún tiempo de operación en el último bit de cada byte. Por ejemplo, envié {0x01, 0x00, 0x00} y el master 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!

    
pregunta Leandro Lima

2 respuestas

1

Aparentemente, el problema era que la tierra no estaba conectada. Mi vergüenza, lo siento!

    
respondido por el Leandro Lima
1

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

En general, el dispositivo maestro enviará un comando al esclavo que solicita 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 está siendo cancelado fuera del registro de TX, el registro de RX también se está completando. Pero el esclavo no está enviando nada todavía porque todavía está recibiendo el comando. El resultado final es que el maestro ahora tiene un byte en su búfer RX que debe descartarse. Este valor generalmente es {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 uses SPI_I2S_ReceiveData () o algo similar.

Una vez que se envía el comando (y se borra el registro de RX), el maestro envía "bytes ficticios" para que cree pulsos de reloj para el esclavo. Generalmente, este puede ser cualquier valor, pero depende del esclavo.

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

    
respondido por el bitsmack

Lea otras preguntas en las etiquetas