Hello everyone,
I am trying to communication between two STM32F4 microcontroller using SPI protocol. here i am using SPI3. Here i am configuring one STM32 as master & the other as Slave. I have interconnected the SPI_NSS pin of the master & the salve, I have configured both the SPI_NSS pins as Hardwre NSS management, in case of the master i have also set the SSOE bit in the SPI_CR1 register.
I am using Interrupt base communication in both master & slave.In the code i am continuously transmitting 10 bytes of data from the master to the slave, but in most of the cases the slave is receiving garbage or altered data, there is no fix pattern in which the data get altered, when the slaves receives the actual data from the master then it responds by sending it's actual data to the master but when slave receives altered/garbage data from the master the it also send altered/garbage data to the master.
Below is the SPI initialization code of the master
void SPI3_Master_init(void) { GPIO_InitTypeDef GPIO_InitStruct; SPI_InitTypeDef SPI_InitStruct; // enable peripheral clock RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI3, ENABLE); // enable clock for used IO pins RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); /* configure pins used by SPI3 * PC10 = SCK * PC11 = MISO * PC12 = MOSI */ GPIO_InitStruct.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_11 | GPIO_Pin_10; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStruct.GPIO_OType = GPIO_OType_PP; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_Init(GPIOA, &GPIO_InitStruct); // connect SPI3 pins to SPI alternate function GPIO_PinAFConfig(GPIOC, GPIO_PinSource10, GPIO_AF_SPI3); GPIO_PinAFConfig(GPIOC, GPIO_PinSource11, GPIO_AF_SPI3); GPIO_PinAFConfig(GPIOC, GPIO_PinSource12, GPIO_AF_SPI3); // enable clock for used IO pins RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); GPIO_PinAFConfig(GPIOA, GPIO_PinSource15,GPIO_AF_SPI3); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; GPIO_Init( GPIOA, &GPIO_InitStructure ); SPI_InitStruct.SPI_Direction = SPI_Direction_2Lines_FullDuplex; // set to full duplex SPI_InitStruct.SPI_Mode = SPI_Mode_Master; // transmit in master mode, NSS pin has SPI_InitStruct.SPI_DataSize = SPI_DataSize_8b; // one packet of data is 8 bits wide SPI_InitStruct.SPI_CPOL = SPI_CPOL_Low; // clock is low when idle SPI_InitStruct.SPI_CPHA = SPI_CPHA_1Edge; // data sampled at first edge SPI_InitStruct.SPI_NSS = SPI_NSS_Hard; // set the NSS HARD SPI_InitStruct.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256; // SPI frequency is SPI_InitStruct.SPI_FirstBit = SPI_FirstBit_MSB;// data is transmitted MSB first SPI_Init(SPI1, &SPI_InitStruct); SPI_SSOutputCmd(SID_MASTER_SPI,ENABLE); //Set SSOE bit in SPI_CR1 register SPI_Cmd(SPI3, ENABLE); // enable SPI3 }
This is the SPI ISR code of the Master for transmitting & receiving 10 bytes of data to & from the slave.
void SPI3_IRQHandler(void) { unsigned char rx; static unsigned short int count = 0, i = 0 ; if (SPI_I2S_GetITStatus(SPI3, SPI_I2S_IT_TXE) == SET) { if(count < 10) { SPI3->DR = count; count++ ; } else { SPI_Cmd(SPI3, DISABLE); } } if (SPI_I2S_GetITStatus(SPI3, SPI_I2S_IT_RXNE) == SET) { master_rev_buff[i] = SPI3->DR ; i++ ; } }
Below is the SPI initialization code of the Slave
void SPI3_Slave_init(void) { GPIO_InitTypeDef GPIO_InitStruct; SPI_InitTypeDef SPI_InitStruct; // enable peripheral clock RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI3, ENABLE); // enable clock for used IO pins RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); /* configure pins used by SPI3 * PC10 = SCK * PC11 = MISO * PC12 = MOSI */ GPIO_InitStruct.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_11 | GPIO_Pin_10; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStruct.GPIO_OType = GPIO_OType_PP; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_Init(GPIOA, &GPIO_InitStruct); // connect SPI3 pins to SPI alternate function GPIO_PinAFConfig(GPIOC, GPIO_PinSource10, GPIO_AF_SPI3); GPIO_PinAFConfig(GPIOC, GPIO_PinSource11, GPIO_AF_SPI3); GPIO_PinAFConfig(GPIOC, GPIO_PinSource12, GPIO_AF_SPI3); // enable clock for used IO pins RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); GPIO_PinAFConfig(GPIOA, GPIO_PinSource15,GPIO_AF_SPI3); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; GPIO_Init( GPIOA, &GPIO_InitStructure ); SPI_InitStruct.SPI_Direction = SPI_Direction_2Lines_FullDuplex; // set to full duplex SPI_InitStruct.SPI_Mode = SPI_Mode_Slave; // transmit in slave mode, NSS pin has SPI_InitStruct.SPI_DataSize = SPI_DataSize_8b; // one packet of data is 8 bits wide SPI_InitStruct.SPI_CPOL = SPI_CPOL_Low; // clock is low when idle SPI_InitStruct.SPI_CPHA = SPI_CPHA_1Edge; // data sampled at first edge SPI_InitStruct.SPI_NSS = SPI_NSS_Hard; // set the NSS HARD SPI_InitStruct.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256; // SPI frequency is SPI_InitStruct.SPI_FirstBit = SPI_FirstBit_MSB;// data is transmitted MSB first SPI_Init(SPI1, &SPI_InitStruct); SPI_Cmd(SPI3, ENABLE); // enable SPI3 }
This is the SPI ISR code of the Slave for receiving & transmitting 10 bytes of data from & to the Master.
void SPI3_IRQHandler(void) { unsigned char rx; static unsigned short int count = 0, i = 0 ; if (SPI_I2S_GetITStatus(SPI3, SPI_I2S_IT_TXE) == SET) { SPI3->DR = 0xFC ; } if (SPI_I2S_GetITStatus(SPI3, SPI_I2S_IT_RXNE) == SET) { Slave_rev_buff[i] = SPI3->DR ; i++ ; } }