2018-03-03 09:04 AM
Hi,
I beleive i have initialised my master STM32 correctly somehow i cant get my slave to understand my master.
My problem is my slave does not seem to understand the master, i have tried various things, like using SPI2 instead of SPI1, did not work, any help would be appreciated.
void init_spi_gpio(void)
{
GPIO_InitTypeDef SPI_GPIOStruct;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
/*
* PB3 - SCK
* PB4 - MISO
* PB5 - MOSI
* */
SPI_GPIOStruct.GPIO_Mode = GPIO_Mode_AF;
SPI_GPIOStruct.GPIO_OType = GPIO_OType_OD;
SPI_GPIOStruct.GPIO_Pin = GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5;
SPI_GPIOStruct.GPIO_PuPd = GPIO_PuPd_UP;
SPI_GPIOStruct.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_Init(GPIOB, &SPI_GPIOStruct);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource3, GPIO_AF_SPI1);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource4, GPIO_AF_SPI1);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource5, GPIO_AF_SPI1);
/*NSS Pin Config */
GPIO_InitTypeDef SPI_SSPIN_Struct;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
SPI_SSPIN_Struct.GPIO_Mode = GPIO_Mode_OUT;
SPI_SSPIN_Struct.GPIO_OType = GPIO_OType_PP;
SPI_SSPIN_Struct.GPIO_Pin = GPIO_Pin_15;
SPI_SSPIN_Struct.GPIO_PuPd = GPIO_PuPd_UP;
SPI_SSPIN_Struct.GPIO_Speed = GPIO_High_Speed;
GPIO_Init(GPIOA, &SPI_SSPIN_Struct);
//GPIO_SetBits(GPIOA,GPIO_Pin_15);
}
void init_spi_module(void)
{
SPI_InitTypeDef SPI_InitStruct;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);
SPI_StructInit(&SPI_InitStruct);
SPI_InitStruct.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;
SPI_InitStruct.SPI_CPHA = SPI_CPHA_1Edge;
SPI_InitStruct.SPI_CPOL = SPI_CPOL_Low;
//SPI_InitStruct.SPI_CRCPolynomial = 0x00;
SPI_InitStruct.SPI_DataSize = SPI_DataSize_8b;
SPI_InitStruct.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
SPI_InitStruct.SPI_FirstBit = SPI_FirstBit_LSB;
SPI_InitStruct.SPI_Mode = SPI_Mode_Master;
SPI_InitStruct.SPI_NSS = SPI_NSS_Soft| SPI_NSSInternalSoft_Set;
SPI_Init(SPI1, &SPI_InitStruct);
SPI_Cmd(SPI1, ENABLE);
}
int main(void)
{
uint8_t RxChar;
SystemInit();
SysTick_Init();
RCC_HSICmd(ENABLE);
init_led_gpios();
init_spi_gpio();
init_spi_module();
init_usart2_comm_module();
init_usart2_gpio();
init_powerup();
USART_TX_string(''Reset!\n\r'');
GPIO_SetBits(GPIOD, GPIO_Pin_12);
while (1)
{
write_to_MAX7219(0x0A, 0x05);
Delay_ms(500);
MAX7219_displayNumber(25);
}
}
void write_to_MAX7219(uint8_t addr, uint8_t data)
{
uint16_t Addr, Data, Data_to_send;
Addr = (uint16_t)addr;
Data = (uint16_t)data;
Data_to_send = ( (Addr<<8 ) & 0xFF00 ) | Data ;
GPIO_ResetBits(GPIOA,GPIO_Pin_15);
SPI_send_word( Data_to_send );
GPIO_SetBits(GPIOA,GPIO_Pin_15);
}
void SPI_send_word(uint16_t byte)
{
while ( ( (SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_BSY) ) == SET))
;
SPI_I2S_SendData(SPI1, (uint16_t) byte);
while ( ( (SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_TXE) ) != SET))
;
}�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?
#stm32f4-spi #stm32f411ve #spi-communication #max7219
Solved! Go to Solution.
2018-03-06 12:25 AM
Yea, i kinda overlooked the fact that the MAX7219 accepts MSB first, so i had to initialise my SPI module on Master with MSB first and the Datasize as 16b, and it worked. The send routine and write routine that initialised the MAX chip were actually correct, the SPI initialisation was a bit unclean.
Here's the project what i actually wanted to do, obtain Time information from a GPS Module and display it over a 7 Segment Display over SPI.
2018-03-03 03:47 PM
Is PA15 output to the slave chip as some form of framing/enable? You then need to wait until the data actually were clocked out (i.e. check for BUSY *after* the data were sent).
Oscilloscope/Logic analyzer is a must.
JW
2018-03-04 05:46 AM
PA15 is configured as NSS yes. It was a really good idea with Logic ananlyzer. As it turned out, the SPI communication was not working as clean as i expected. I tried waiting after the busy flag was not set any more, but it did not really help. What i did was Set the SS pin to high on initiaslising in the Init routine, and im using SPI2 now, like this:
GPIO_Init(GPIOB, &SPI_SSPIN_Struct);
GPIO_SetBits(GPIOB,GPIO_Pin_12);�?�?
I pull the line Low before sending a byte, then pull it high then again low. The send byte routine looks like this now,
void SPI_send_byte(uint8_t byte)
{
GPIO_ResetBits(GPIOB, GPIO_Pin_12);
SPI_I2S_SendData(SPI2,(uint16_t) byte);
while ( ( (SPI_I2S_GetFlagStatus(SPI2,SPI_I2S_FLAG_TXE) )!= SET))
;
while ( ( (SPI_I2S_GetFlagStatus(SPI2,SPI_I2S_FLAG_BSY) ) == SET))
;
GPIO_SetBits(GPIOB, GPIO_Pin_12);
GPIO_ResetBits(GPIOD, GPIO_Pin_12);
}�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?
and i sent 3 dummy bytes over SPI from main routine, and i could see the bytes,
The problem is, somehow my 7 segment display expects 16 bit data on the bus, im not sure sending 2 consecutive 8 bit data would work, it does not till now. I tried sending 16bit data instead of two 8-bit, it still does not work as expected.
2018-03-04 09:04 AM
Then the usual procedure applies: check waveforms against the target chip's datasheet (mutual positioning of data and clock and slave select), check connections/continuity, including (or, better, starting with) ground.
With SPI and lengthy wires, also try reducing the pin's slew rate in GPIO_OSPEEDR. And you want a separate return for each signal (clock, data), independent of supply ground.
(And I personally recommend against using breadboards).
JW
2018-03-06 12:25 AM
Yea, i kinda overlooked the fact that the MAX7219 accepts MSB first, so i had to initialise my SPI module on Master with MSB first and the Datasize as 16b, and it worked. The send routine and write routine that initialised the MAX chip were actually correct, the SPI initialisation was a bit unclean.
Here's the project what i actually wanted to do, obtain Time information from a GPS Module and display it over a 7 Segment Display over SPI.