cancel
Showing results for 
Search instead for 
Did you mean: 

Problem in communication 2 slaves and 1 master using SPI.

HAlau.1
Associate II

hello everyone, I have a problem in communication 2 slaves and 1 master using SPI.

master will send a code to activate one of the slaves and then the master will receive data from the slave, but sending the initial data is always wrong and only when the reset button is pressed the sending of data becomes correct and so on.

does anyone know where the error is? and please give me a solution.

thank you

19 REPLIES 19
HAlau.1
Associate II

my scenario is that the master will send a character, when the character "1" is sent via serial, slave 1 will be active and send data, then the data will be received by master, when the character "2" is sent via serial, slave 2 will be active and send data, then the data is received by the master, the problem is how to make the slave active only when the appropriate characters have been sent ("1" for salve1 and "2" for slave2). with the program that I made has been running quite well, but when I want to move from slave1 to slave2 so that the data received is correct, I have to press the reset button first, if my code is needed I will send it, I hope there will be a solution to this problem, thank you

What does the datasheet of the slaves say about the protocol requirements? How are the master and slave supposed to synchronize?

HAlau.1
Associate II

thank you,

I use STM32F427VI for master and slave, i try send "hello" from slave1 and "world" from slave2,

I don't know much about the synchronization of master and slave, but what I know between slave and master is that the clock must be the same and for communication the SS pin must be active low, and it works when I only use 1 slave

How are the slaves connected? How is SPI configured on the mater and on the slaves?

HAlau.1
Associate II
/* SPI1 init function */ MASTER
static void MX_SPI1_Init(void)
{
 
  /* SPI1 parameter configuration*/
  hspi1.Instance = SPI1;
  hspi1.Init.Mode = SPI_MODE_MASTER;
  hspi1.Init.Direction = SPI_DIRECTION_2LINES;
  hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
  hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;
  hspi1.Init.CLKPhase = SPI_PHASE_2EDGE;
  hspi1.Init.NSS = SPI_NSS_SOFT;
  hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_16;
  hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
  hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
  hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
  hspi1.Init.CRCPolynomial = 10;
  if (HAL_SPI_Init(&hspi1) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }
 
}
 
/* SPI4 init function */ SLAVE1
static void MX_SPI4_Init(void)
{
 
  /* SPI4 parameter configuration*/
  hspi4.Instance = SPI4;
  hspi4.Init.Mode = SPI_MODE_SLAVE;
  hspi4.Init.Direction = SPI_DIRECTION_2LINES;
  hspi4.Init.DataSize = SPI_DATASIZE_8BIT;
  hspi4.Init.CLKPolarity = SPI_POLARITY_LOW;
  hspi4.Init.CLKPhase = SPI_PHASE_2EDGE;
  hspi4.Init.NSS = SPI_NSS_SOFT;
  hspi4.Init.FirstBit = SPI_FIRSTBIT_MSB;
  hspi4.Init.TIMode = SPI_TIMODE_DISABLE;
  hspi4.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
  hspi4.Init.CRCPolynomial = 10;
  if (HAL_SPI_Init(&hspi4) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }
 
}
 
/* SPI4 init function */ SLAVE 2
static void MX_SPI4_Init(void)
{
 
  /* SPI4 parameter configuration*/
  hspi4.Instance = SPI4;
  hspi4.Init.Mode = SPI_MODE_SLAVE;
  hspi4.Init.Direction = SPI_DIRECTION_2LINES;
  hspi4.Init.DataSize = SPI_DATASIZE_8BIT;
  hspi4.Init.CLKPolarity = SPI_POLARITY_LOW;
  hspi4.Init.CLKPhase = SPI_PHASE_2EDGE;
  hspi4.Init.NSS = SPI_NSS_SOFT;
  hspi4.Init.FirstBit = SPI_FIRSTBIT_MSB;
  hspi4.Init.TIMode = SPI_TIMODE_DISABLE;
  hspi4.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
  hspi4.Init.CRCPolynomial = 10;
  if (HAL_SPI_Init(&hspi4) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }
 
}

0690X00000DBbJEQA1.png

thank you, my configuration like this

S.Ma
Principal

It can be done, although it won't be datarate efficient. Once all slaves receive the first data byte after NSS fall edge, all slave will need master pause to go to interrupt, read the header byte, and decide which slave will activate its MISO line (the other ones will transmit without physical pin).

Once NSS rising edge (and EXTI interrupt?), all slaves disable their MISO and listen to the next round of exchange.

It is still not clear to me how do the slaves recognize when the master starts sending data. What does your code on the slave about that?

You are using soft NSS on the slaves. Why?

Do you know how SPI works?

HAlau.1
Associate II

thank you beredindi, sorry I'm new about this, what should I do and what's the difference between soft NSS and hard NSS? Does it have to be a different type of slave and master? and this is my code in slave

  __HAL_SPI_ENABLE(&hspi4);
	  HAL_SPI_Receive (&hspi4, txslave2, 6, 50);
 
	  input=atoi((char *)txslave2);
 
	  if (input==2){
	  __HAL_SPI_ENABLE(&hspi4);
//	  HAL_GPIO_WritePin(GPIOE, GPIO_PIN_4,GPIO_PIN_SET);
	  HAL_SPI_Transmit (&hspi4,outputBuffer2, 6, 50);
//	  HAL_SPI_Receive (&hspi4, spiRxBuf, 1, 50);
//	  HAL_GPIO_WritePin(GPIOE, GPIO_PIN_4,GPIO_PIN_SET);
	  }

HAlau.1
Associate II

thank you @. , I understand what you're talking about, but I was confused when writing it in the master and slave program, can you give a little sample code?

> what should I do

  • Read some textbook on communication protocols in general, and understand how SPI works, what is the function of NSS (most literature calls it CS), clock and data signals.
  • Read the SPI chapter in the reference manual carefully to understand how the SPI controller in your MCU works.
  • Get a clear idea on how can the master and the slave SPI interface is going to synchronize to each other.