2015-08-12 03:21 AM
Hello,
I've two STM32F4 Boards which I want to send data to each other via SPI. I think that I configured the master board (STM32F411 Nucleo board) well, because at the scope, I ''saw'' the sended data. My problem is the receiving of this data with the SPI slave (STM32F429 Discovery board). I want to receive the data at first in the main loop without an interrupt. My questions: is the CS-pin well declared and connected with SPI interface? What is the typical sequence to receive data, which flag should I check? (I read a lot of examples and every example uses another flag, is there an overview about this SPI flags?) This is my slave-code:// SPI3 SCK
#define SPI3_SCK_PinSource GPIO_PinSource10
#define SPI3_SCK_Pin GPIO_Pin_10
#define SPI3_SCK_Bank GPIOC
// SPI3 MISO
#define SPI3_MISO_PinSource GPIO_PinSource11
#define SPI3_MISO_Pin GPIO_Pin_11
#define SPI3_MISO_Bank GPIOC
// SPI3 MOSI
#define SPI3_MOSI_PinSource GPIO_PinSource12
#define SPI3_MOSI_Pin GPIO_Pin_12
#define SPI3_MOSI_Bank GPIOC
// SPI3 CS
#define SPI3_CS_PinSource GPIO_PinSource15
#define SPI3_CS_Pin GPIO_Pin_15
#define SPI3_CS_Bank GPIOA
This is the SPI.c:
/*
**
** SPI3.c
**
**
**********************************************************************/
/*
Device: STM32F429 Discovery
**********************************************************************/
#include ''stm32f4xx_conf.h''
#include ''SPI3.h''
#include ''definitions.h''
void
SPI3_Slave_init()
{
/* Clocks für SPI3 enablen*/
RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI3, ENABLE);
/* Definitionsstruct */
SPI_InitTypeDef SPI_InitTypeDefStruct;
// Baudraten Prescaler gibt Geschwindigkeit an
// 2 = schnellste
SPI_InitTypeDefStruct.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8;
// Richtung der Datenverbindung
SPI_InitTypeDefStruct.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
//Master oder Slave
SPI_InitTypeDefStruct.SPI_Mode = SPI_Mode_Slave;
//Größe der Datenpakete - 8 oder 16 bit
SPI_InitTypeDefStruct.SPI_DataSize = SPI_DataSize_8b;
//ChipSelect durch Hardware oder Software
SPI_InitTypeDefStruct.SPI_NSS = SPI_NSS_Soft;
//Reihenfolge der Daten - Little Endian oder Big Endian (LSB oder MSB)
//Sollte bei beiden Endgeräten identisch sein
//Wikipedia: Byte-Reihenfolge
SPI_InitTypeDefStruct.SPI_FirstBit = SPI_FirstBit_MSB;
//Clock Polarity --> Muss bei beiden Endgeräten identisch sein
SPI_InitTypeDefStruct.SPI_CPOL = SPI_CPOL_Low;
//Definiert Flanke, ab wann Daten empfangen werden soll (1st oder 2nd Edge)
SPI_InitTypeDefStruct.SPI_CPHA = SPI_CPHA_2Edge;
//Wird im Beispiel nicht angewendet
//SPI_InitTypeDefStruct.SPI_CRCPolynomial = ;
//SPI initialisieren
SPI_Init(SPI3, &SPI_InitTypeDefStruct);
/* Clocks für GPIOs enablen*/
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOC, ENABLE);
/* GPIO-Initialisierungsstruct*/
GPIO_InitTypeDef GPIO_InitStruct;
/*-------- Configuring SCK-MOSI-MISO --------*/
GPIO_InitStruct.GPIO_Pin = SPI3_SCK_Pin;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(SPI3_SCK_Bank, &GPIO_InitStruct);
GPIO_InitStruct.GPIO_Pin = SPI3_MISO_Pin | SPI3_MOSI_Pin;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(SPI3_MISO_Bank, &GPIO_InitStruct);
/*-------- Configuring ChipSelect-Pin --------*/
GPIO_InitStruct.GPIO_Pin = SPI3_CS_Pin;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(SPI3_CS_Bank, &GPIO_InitStruct);
/*Funktion der PINs eindeutig definieren */
GPIO_PinAFConfig(SPI3_SCK_Bank, SPI3_SCK_PinSource, GPIO_AF_SPI3);
GPIO_PinAFConfig(SPI3_MISO_Bank, SPI3_MISO_PinSource, GPIO_AF_SPI3);
GPIO_PinAFConfig(SPI3_MOSI_Bank, SPI3_MOSI_PinSource, GPIO_AF_SPI3);
/* SPI enablen */
SPI_Cmd(SPI3, ENABLE);
SPI_NSSInternalSoftwareConfig(SPI3, SPI_NSSInternalSoft_Set);
}
And the main.c:
/*
**
** Main.c
**
**
**********************************************************************/
/*
Device: STM32F429 Discovery
**********************************************************************/
#include ''stm32f4xx_conf.h''
#include ''stm32f4xx_spi.h''
#include ''definitions.h''
#include ''SPI3.h''
#include ''stdbool.h''
uint8_t received_data;
GPIO_InitTypeDef GPIO_InitStruct;
uint8_t rxData;
bool
a=
false
;
int
main(
void
)
{
//System Initialization (Clock Setup and stuff like that)
SystemInit();
//initUserLED();
//Enable GPIO Clock
SPI3_Slave_init();
while
(1)
{
rxData=0x00;
if
(SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_RXNE) == SET){
a=
true
;
// Application never reaches here!
rxData = SPI3->DR;
}
if
(SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_TXE) == SET){
if
(a){
SPI1->DR = 0xAB;
a=
false
;
}
}
}
}
In the main.c, I never reach the part, where the bool a is set. What is the main routine to receive 1 byte, many bytes?
The master is always sending 1 byte every cycle (tx=0xB5 // only test value) and on the scope I can see the 0xB5.
Thanks for your help!
#spitwoboards #spi-slave
2015-08-18 05:08 AM
Hi kassner.marcel,
If you can migrate to the Cube, it will be easier for you to start with an example on the STM32CubeF4 package.Ex: STM32Cube_FW_F4_V1.7.0\Projects\STM32F429I-Discovery\Examples\SPI\SPI_FullDuplex_ComPolling.There are also examples in the standard peripheral library where the data transfer is made in DMA or IT mode (STM32F4xx_DSP_StdPeriph_Lib\Project\STM32F4xx_StdPeriph_Examples\SPI\SPI_TwoBoards).-Mayla-To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.