Skip to main content
Cözde.1
Associate
December 19, 2019
Question

I would like to make SPI communication with HAL library. I want to read the incoming data with the Receive function, but I cannot get an answer. Is there anyone who can help?

  • December 19, 2019
  • 12 replies
  • 3337 views

SPI

This topic has been closed for replies.

12 replies

Ala
Senior
December 24, 2019

when you choose one of the SPIs, say for example, SPI1, some of the pins are selected as TX, RX and CLK, standing for transmitter, receiver, and clock pins. you can receive the data on the RX pin. the relevant HAL function would be HAL_SPI_Receive().

Cözde.1
Cözde.1Author
Associate
December 24, 2019

BSP_LED_Off(LED2);

HAL_SPI_Transmit(&SpiHandle,&adres,1,HAL_MAX_DELAY);

HAL_SPI_Receive(&SpiHandle,&data,1,HAL_MAX_DELAY);

BSP_LED_On(LED2);

That's part of my code. Sending data via transmit I want to read the data sent by the receiver but it shows 0.

Ala
Senior
December 24, 2019

are you sure that "data" contains anything? because in the above code I can see nothing... have you initialized "data"?

Cözde.1
Cözde.1Author
Associate
December 24, 2019

#include "main.h"

#define MASTER_BOARD

SPI_HandleTypeDef SpiHandle;

uint8_t aTxBuffer = 0x55;

uint8_t aRxBuffer;

void SystemClock_Config(void);

static void Error_Handler(void);

void spi_Init(void);

//static uint16_t Buffercmp(uint8_t *pBuffer1, uint8_t *pBuffer2, uint16_t BufferLength);

int main(void)

{

 HAL_Init();

 SystemClock_Config();

 spi_Init();

 BSP_LED_Init(LED2);

 // CS5532_Init();

#ifdef MASTER_BOARD

 SpiHandle.Init.Mode = SPI_MODE_MASTER;

#else

 SpiHandle.Init.Mode = SPI_MODE_SLAVE;

#endif

 if(HAL_SPI_Init(&SpiHandle) != HAL_OK)

 {

   Error_Handler();

 }

/*

#ifdef MASTER_BOARD

 BSP_PB_Init(BUTTON_USER, BUTTON_MODE_GPIO);

 while (BSP_PB_GetState(BUTTON_USER) != GPIO_PIN_RESET)

 {

   BSP_LED_Toggle(LED2);

   HAL_Delay(100);

  }

 BSP_LED_Off(LED2);

#endif */

 HAL_SPI_Transmit(&SpiHandle, &aTxBuffer,1, 5000);

HAL_SPI_Receive(&SpiHandle,&aRxBuffer,1, 5000);

 HAL_Delay(1);

 BSP_LED_Off(LED2);

 while (1)

 {

 }

}

static void Error_Handler(void)

{

 while(1)

 {

   BSP_LED_Toggle(LED2);

   HAL_Delay(1000);

 }

}

void SystemClock_Config(void)

{

 RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

 RCC_OscInitTypeDef RCC_OscInitStruct = {0};

 /* MSI is enabled after System reset, activate PLL with MSI as source */

 RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_MSI;

 RCC_OscInitStruct.MSIState = RCC_MSI_ON;

 RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_6;

 RCC_OscInitStruct.MSICalibrationValue = RCC_MSICALIBRATION_DEFAULT;

 RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;

 RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_MSI;

 RCC_OscInitStruct.PLL.PLLM = 1;

 RCC_OscInitStruct.PLL.PLLN = 40;

 RCC_OscInitStruct.PLL.PLLR = 2;

 RCC_OscInitStruct.PLL.PLLP = 7;

 RCC_OscInitStruct.PLL.PLLQ = 4;

 if(HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)

 {

   while(1);

 }

 RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);

 RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;

 RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;

 RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; 

 RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; 

 if(HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4) != HAL_OK)

 {

   while(1);

 }

}

void spi_Init(void)

{

  SpiHandle.Instance              = SPIx;

  SpiHandle.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_256;

  SpiHandle.Init.Direction        = SPI_DIRECTION_2LINES;

  SpiHandle.Init.CLKPhase         = SPI_PHASE_1EDGE;

  SpiHandle.Init.CLKPolarity      = SPI_POLARITY_LOW;

  SpiHandle.Init.DataSize         = SPI_DATASIZE_8BIT;

  SpiHandle.Init.FirstBit         = SPI_FIRSTBIT_MSB;

  SpiHandle.Init.TIMode           = SPI_TIMODE_DISABLE;

  SpiHandle.Init.CRCCalculation   = SPI_CRCCALCULATION_DISABLE;

  SpiHandle.Init.CRCPolynomial    = 7;

  SpiHandle.Init.CRCLength        = SPI_CRC_LENGTH_8BIT;

  SpiHandle.Init.NSS              = SPI_NSS_SOFT;

  SpiHandle.Init.NSSPMode         = SPI_NSS_PULSE_DISABLE;

}

/*static uint16_t Buffercmp(uint8_t* pBuffer1, uint8_t* pBuffer2, uint16_t BufferLength)

{

 while (BufferLength--)

 {

   if((*pBuffer1) != *pBuffer2)

   {

     return BufferLength;

   }

   pBuffer1++;

   pBuffer2++;

 }

 return 0;

} */

#ifdef USE_FULL_ASSERT

void assert_failed(uint8_t *file, uint32_t line)

{

   while (1)

 {

 }

}

#endif

my full code is as follows. can you help

Tesla DeLorean
Guru
December 24, 2019

Which STM32 part are we talking about?

I think if you want two way comms you'd do better using the Transmit_Receive function.

You'd also want to consider how you're driving the chip-select into the unspecified target device.

Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..
Cözde.1
Cözde.1Author
Associate
December 25, 2019

I use the STM32 l476 card. Cs5532 I want to get information from ADC. For this, I first tried to communicate between 2 stm32. I wonder why the Receive function doesn't work.

S.Ma
Principal
December 25, 2019

safe SPI is 4 wires MOSI/MISO/SCK/NSS

receive and transmit occur at the same time so you need to use transmit_receive

There are (too) simple examples in Nucleo project folders... to help you get started.

Cözde.1
Cözde.1Author
Associate
December 25, 2019

Only transmitreceive is used in the examples I could not see the example related to Receive

S.Ma
Principal
December 25, 2019

Still use transmit receive, even if you don't configure all SPI GPIOs.]

All works fine with STM32L496 SPI master and slave modes.

Cözde.1
Cözde.1Author
Associate
December 26, 2019

can you throw sample code

S.Ma
Principal
December 26, 2019

My code for SPI is quite rich as it includes a master/slave mode with interrupts and DMA.

So I'll show here the 5% which is for master mode extract code. 4 wire SPI on L4R5 @12MHz with SYSCLK = 48MHz

16 bit SPI mode

HAL_StatusTypeDef SPIP_MasterConfigureSpi(SPI_HandleTypeDef *hspi){
 hspi->Instance = SPI2;
 hspi->Init.Direction = SPI_DIRECTION_2LINES;
 hspi->Init.CLKPhase = SPI_PHASE_1EDGE;
 hspi->Init.CLKPolarity = SPI_POLARITY_LOW;
 hspi->Init.DataSize = SPI_DATASIZE_16BIT;
 hspi->Init.FirstBit = SPI_FIRSTBIT_MSB;
 hspi->Init.TIMode = SPI_TIMODE_DISABLE;
 hspi->Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
 hspi->Init.CRCPolynomial = 7;
 hspi->Init.CRCLength = SPI_CRC_LENGTH_8BIT;
 hspi->Init.NSS = SPI_NSS_SOFT;
 hspi->Init.NSSPMode = SPI_NSS_PULSE_DISABLE;
 hspi->Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_4;//16;
 hspi->Init.Mode = SPI_MODE_MASTER;
 return (HAL_SPI_Init(hspi));
}
 
void SPIP_MasterConfigureDma(SPI_HandleTypeDef *hspi){
 /* Configure the DMA handler for Transmission process */
 pSPIP->hdma_tx->Instance = DMA1_Channel2;//DMA1_Channel5;
 pSPIP->hdma_tx->Init.Request = DMA_REQUEST_SPI2_TX;//DMA_REQUEST_1;
 pSPIP->hdma_tx->Init.Direction = DMA_MEMORY_TO_PERIPH;
 pSPIP->hdma_tx->Init.PeriphInc = DMA_PINC_DISABLE;
 pSPIP->hdma_tx->Init.MemInc = DMA_MINC_ENABLE;
 pSPIP->hdma_tx->Init.PeriphDataAlignment = /*DMA_PDATAALIGN_BYTE;*/ DMA_PDATAALIGN_HALFWORD;
 pSPIP->hdma_tx->Init.MemDataAlignment = /*DMA_MDATAALIGN_BYTE;*/ DMA_MDATAALIGN_HALFWORD;
 pSPIP->hdma_tx->Init.Mode = DMA_NORMAL;
 pSPIP->hdma_tx->Init.Priority = DMA_PRIORITY_HIGH;
 HAL_DMA_Init(pSPIP->hdma_tx);
 /* Associate the initialized DMA handle to the the SPI handle */
 __HAL_LINKDMA(hspi, hdmatx, *(pSPIP->hdma_tx));
 
 /* Configure the DMA handler for Reception process */
 pSPIP->hdma_rx->Instance = DMA1_Channel1;//DMA1_Channel4;
 pSPIP->hdma_rx->Init.Request = DMA_REQUEST_SPI2_RX;//DMA_REQUEST_1;
 pSPIP->hdma_rx->Init.Direction = DMA_PERIPH_TO_MEMORY;
 pSPIP->hdma_rx->Init.PeriphInc = DMA_PINC_DISABLE;
 pSPIP->hdma_rx->Init.MemInc = DMA_MINC_ENABLE;
 pSPIP->hdma_rx->Init.PeriphDataAlignment = /*DMA_PDATAALIGN_BYTE;*/ DMA_PDATAALIGN_HALFWORD;
 pSPIP->hdma_rx->Init.MemDataAlignment = /*DMA_MDATAALIGN_BYTE;*/ DMA_MDATAALIGN_HALFWORD;
 pSPIP->hdma_rx->Init.Mode = DMA_NORMAL;
 pSPIP->hdma_rx->Init.Priority = DMA_PRIORITY_HIGH;
 HAL_DMA_Init(pSPIP->hdma_rx);
 /* Associate the initialized DMA handle to the the SPI handle */
 __HAL_LINKDMA(hspi, hdmarx, *(pSPIP->hdma_rx));
}
 
// this function kicks normally within interrupt for multi-block transfer
HAL_StatusTypeDef SPIP_MasterSerialTransferStart_ISR(SPIP_t* pSPIP){
 if(HAL_SPI_TransmitReceive_DMA(pSPIP->hspi, pSPIP->pMasterSerialTxBuffer, pSPIP->pMasterSerialRxBuffer, SERIAL_BLOCK_SIZE_WORD) != HAL_OK)
 TrapError();
 return HAL_OK;
}