Skip to main content
HAlau.1
Associate II
February 11, 2020
Question

Problem in communication 2 slaves and 1 master using SPI.

  • February 11, 2020
  • 19 replies
  • 3735 views

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

This topic has been closed for replies.

19 replies

S.Ma
Principal
February 11, 2020

How often you turn on a car radio just when a new song starts?

If you want a slave selector header byte, go for I2C

HAlau.1
HAlau.1Author
Associate II
February 11, 2020

thank you

routine but for some slaves only occasionally,

I also use UART to send requests and display the results of receiving data on a serial monitor.

berendi
Principal
February 11, 2020

SPI has no start/stop bit like UART or I2C, so the master and slave should be synchronized by other means. The SPI protocol has the separate chip select (NSS) line for this purpose.

Take two GPIO pins on the master, connect each one to the NSS pin of a slave. Set both of them high (1) initially, and one of them low (0) when you want to talk to that slave.

HAlau.1
HAlau.1Author
Associate II
February 12, 2020

I tried it but it still failed

	 HAL_GPIO_WritePin(GPIOE, GPIO_PIN_7,GPIO_PIN_SET);
	 HAL_GPIO_WritePin(GPIOE, GPIO_PIN_8,GPIO_PIN_SET);
	 if(input==1){
 
	 		__HAL_SPI_ENABLE(&hspi1);
	 		HAL_SPI_Transmit (&hspi1,txslave1, 6, 50);
 
	 		HAL_GPIO_WritePin(GPIOE, GPIO_PIN_7,GPIO_PIN_RESET);
	 		HAL_SPI_Receive (&hspi1, outputBuffer, 6, 50);
	 		HAL_GPIO_WritePin(GPIOE, GPIO_PIN_7,GPIO_PIN_SET);
	 		STM_Serial_Print("data Slave 1 = ");
	 		STM_Serial_Print(outputBuffer);
	 		STM_Serial_Print("\r\n");
	 	}
	 	else if(input==2){
	 		__HAL_SPI_ENABLE(&hspi1);
	 		HAL_SPI_Transmit (&hspi1,txslave2, 6, 50);
 
	 		STM_Serial_Print("wait..\n\r");
	 		HAL_GPIO_WritePin(GPIOE, GPIO_PIN_8,GPIO_PIN_RESET);
	 		HAL_SPI_Receive (&hspi1, outputBuffer2, 6, 50);
	 		HAL_GPIO_WritePin(GPIOE, GPIO_PIN_8,GPIO_PIN_SET);
	 		STM_Serial_Print("data Slave 2 = ");
	 		STM_Serial_Print(outputBuffer2);
	 		STM_Serial_Print("\r\n");
	 	}

berendi
Principal
February 12, 2020

low (0) when you want to talk to that slave.

HAlau.1
HAlau.1Author
Associate II
February 12, 2020

thank you,

if you wish, can you give a simple example of code? because I don't know, where should I put the code to activate NSS

thank you

berendi
Principal
February 12, 2020

Before talking to the slave.

Review the SPI chapter in the reference manual, or some general article in SPI.

HAlau.1
HAlau.1Author
Associate II
February 12, 2020

like this?

  HAL_GPIO_WritePin(GPIOE, GPIO_PIN_8,GPIO_PIN_RESET);

  HAL_SPI_Receive (&hspi1, outputBuffer2, 6, 50);

  HAL_GPIO_WritePin(GPIOE, GPIO_PIN_8,GPIO_PIN_SET);

berendi
Principal
February 12, 2020

If you are only receiving, and never transmitting, yes.

There supposed to be some timing diagrams in the datasheet of the slaves.

You should understand the protocol requirements first, and plan the code accordingly, instead of shooting blindly.

HAlau.1
HAlau.1Author
Associate II
February 13, 2020

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

berendi
Principal
February 13, 2020

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

HAlau.1
HAlau.1Author
Associate II
February 14, 2020

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

berendi
Principal
February 14, 2020

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

HAlau.1
HAlau.1Author
Associate II
February 17, 2020
/* 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

berendi
Principal
February 17, 2020

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?

S.Ma
Principal
February 17, 2020

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.