Skip to main content
michael239955_stm1_st
Associate
March 4, 2014
Question

STM32F051 with SPI: no reception

  • March 4, 2014
  • 3 replies
  • 820 views
Posted on March 04, 2014 at 12:10

Hi,

I have the SPI communication working but do not receive the answer of the slave. I can see the answer on the scope but not in the controller. Can anybody help ?

My main.c

/* Includes ------------------------------------------------------------------*/

&sharpinclude ''main.h''

void spiInit(void);

void spiInit()

{

  SPI_InitTypeDef SPI_InitStructure;

GPIO_InitTypeDef GPIO_InitStructure;

RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA | RCC_AHBPeriph_GPIOB ,ENABLE);

  RCC_APB2PeriphClockCmd (RCC_APB2Periph_SPI1, ENABLE);

     

  SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;

  SPI_InitStructure.SPI_Mode = SPI_Mode_Master;

  SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;

  SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;

  SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;

  SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;

  SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_32;

  SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;

  SPI_InitStructure.SPI_CRCPolynomial = 7;

///////////////////////////////////////////////////////////////////////////// 

// SPI1 Master initialization, SCK -> PA5, MOSI -> PA7

GPIO_StructInit (&GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_7;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;

GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP ;

GPIO_Init(GPIOA, &GPIO_InitStructure);

GPIO_PinAFConfig(GPIOA, GPIO_PinSource5, GPIO_AF_0);

GPIO_PinAFConfig(GPIOA, GPIO_PinSource7, GPIO_AF_0);

// MISO -> PA6

GPIO_StructInit (&GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;

GPIO_Init(GPIOA, &GPIO_InitStructure);

GPIO_PinAFConfig(GPIOA, GPIO_PinSource6, GPIO_AF_0);

// CS or SS chip select -> PA4

GPIO_StructInit (&GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;

GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP ;

GPIO_Init(GPIOA, &GPIO_InitStructure); 

// SPI1

  SPI_Init(SPI1, &SPI_InitStructure);

  SPI_RxFIFOThresholdConfig(SPI1, SPI_RxFIFOThreshold_QF);

  SPI_Cmd(SPI1, ENABLE);

}

void ChipSelectLow()

{

GPIO_WriteBit(GPIOA, GPIO_Pin_4, Bit_RESET);

}

void ChipSelectHigh ()

{

GPIO_WriteBit(GPIOA, GPIO_Pin_4, Bit_SET);

}

uint8_t SPI1_send(uint8_t data){

SPI1->DR = data; // write data to be transmitted to the SPI data register

while( !(SPI1->SR & SPI_I2S_FLAG_TXE) ); // wait until transmit complete

while( !(SPI1->SR & SPI_I2S_FLAG_RXNE) ); // wait until receive complete

while( SPI1->SR & SPI_I2S_FLAG_BSY ); // wait until SPI is not busy anymore

return SPI1->DR; // return received data from SPI data register

}

int main()

{

  uint8_t received_val = 0;

spiInit();

  ChipSelectHigh ();

  //*********************************

  ChipSelectLow ();

SPI_SendData8(SPI1 , 0x01);

  SPI_SendData8(SPI1 , 0x10);

while( !(SPI1->SR & SPI_I2S_FLAG_TXE) ); // wait until transmit complete

while( !(SPI1->SR & SPI_I2S_FLAG_RXNE) ); // wait until receive complete

while( SPI1->SR & SPI_I2S_FLAG_BSY ); // wait until SPI is not busy anymore

  ChipSelectHigh ();

  //*********************************

  

  ChipSelectLow ();

  received_val = SPI1_send (0x81);

  ChipSelectHigh ();

    

  ChipSelectLow ();

  SPI_SendData8(SPI1 , received_val); // test um auf der SPI zu sehen, ob etwas angekommen ist

while( !(SPI1->SR & SPI_I2S_FLAG_TXE) ); // wait until transmit complete

while( !(SPI1->SR & SPI_I2S_FLAG_RXNE) ); // wait until receive complete

while( SPI1->SR & SPI_I2S_FLAG_BSY ); // wait until SPI is not busy anymore

  ChipSelectHigh ();

 

  while (1)

  {

  }

 0690X000006056DQAQ.png 

#stm32f051-spi
This topic has been closed for replies.

3 replies

Tesla DeLorean
Guru
March 4, 2014
Posted on March 04, 2014 at 14:27

If it behaves like other STM32 parts, it might help significantly if you check TXE before randomly jamming data into the SPI->DR (SendData)

Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..
michael239955_stm1_st
Associate
March 4, 2014
Posted on March 04, 2014 at 14:41

Finally found it myself! :)

 one thing is that MISO has to be configured GPIO_Mode_AF and not GPIO_Mode_IN:

// MISO -> PA6

GPIO_StructInit (&GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;

GPIO_Init(GPIOA, &GPIO_InitStructure);

GPIO_PinAFConfig(GPIOA, GPIO_PinSource6, GPIO_AF_0);

the main now looks like:

uint8_t Send( uint8_t data)

{

  SPI_SendData8(SPI1, data);

  while( SPI1->SR & SPI_I2S_FLAG_BSY ); // wait until SPI is not busy anymore

  return SPI_ReceiveData8(SPI1);

}

int main()

{

  uint8_t received_val[4];

spiInit();

  

  //*********************************

  ChipSelectLow ();

received_val[0]=Send(0x01);

  received_val[1]=Send(0x10);

  ChipSelectHigh ();

  //*********************************

  

  //*********************************

  ChipSelectLow ();

  received_val[2]=Send(0x81);

  received_val[3]=Send(0x00);

  ChipSelectHigh ();

  //*********************************

    

  ChipSelectLow ();

  SPI_SendData8(SPI1 , received_val[3]); // test um auf der SPI zu sehen, ob etwas angekommen ist

  while( SPI1->SR & SPI_I2S_FLAG_BSY ); // wait until SPI is not busy anymore

  ChipSelectHigh ();

 

  while (1)

  {

  }

}

I hope it helps if anybody ist searching for a long time like me.

I always read that somebody found the problem but never the code was published.
Tesla DeLorean
Guru
March 4, 2014
Posted on March 04, 2014 at 16:22

The code originally posted look a lot like some other stuff that's been posted in recent days, no real idea where that came from.

Yes the Mode_IN is not what SPI pins are typically set too, most all STM32 parts other than the F1 have peripheral pins set to AF, and the direction controlled by the peripheral itself.

At better source of SPI example code might be those in the library for the EVAL boards?

STM32F0xx_StdPeriph_Lib_V1.0.0\Project\STM32F0xx_StdPeriph_Examples\SPI\SPI_TwoBoards

Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..