cancel
Showing results for 
Search instead for 
Did you mean: 

I am trying to use SPI2 on an STM32F407 processor and can’t get it to work.

BRowl
Associate II

 I am using SPI1 to communicate with an IMU, which work perfectly. I used the same initialization code for SPI2 making changes for SPI2 and initialize PB13, PB14 and PB15 as SCLK, MISO and MOSI. It doesn’t work and I have run out of ideas. When SPI1 is initialized its SCLK pin immediately goes high, clock is high at idle, but when SPI2 is initialized its SCLK pin never goes high. I have tried initializing PB13 as an individual port and it works fine, goes high when set high and low when set low. So, it appears the hardware is OK. I have also eliminated all the rest of the code, still doesn’t work. I tried using other pins for SPI2, they don’t work either.  My SPI2 Init is attached.  

1 ACCEPTED SOLUTION

Accepted Solutions
Chris1
Senior III

You have: RCC_APB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);

but GPIOs are actually on AHB1 bus.

Try: RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);

(As JW pointed out already).

View solution in original post

6 REPLIES 6
turboscrew
Senior III

Have you tried writing or reading? The clock starts when data is written in the TX-register.

If it still doesn't work, I recommend reading the status register and checking if there are errors.

BRowl
Associate II

I did try sending data and there was still no clock on PB13, it was always low. I compared the SPI1 status register to the SPI2 status register immediately after a data send. Both status registers were exactly the same, all flags were low except the Receive (RXNE) and the Over Run (OVR), they were both set. My checking the flags may be why SPI1 OVR was set. I wanted to verify PB13 was still a functional port so I configured PB13 as output port just before I ran the SPI2 Init code ( I though I had commented out the SPI2 Init code) and much to my surprise when I ran the SPI2 send routine I had a clock on PB13. So, this seems to indicate that there is something in my “Initialize SPI2 pins�? code that is not correct, but I sure don’t see anything in that section of the code that looks wrong.

>      // enable clock for used IO pins

>   RCC_APB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);

You would see this problem, would you try to read back the GPIO registers and check.

JW

BRowl
Associate II

Good suggestion, thanks.

I read the four GPIOB registers being loaded by GPIO_Init and this is what I found. 

When PB13 is initialized as an output port and it works as an output port and the four registers are:

Mode_AF        = 0x4000280

OType_PP      = 0x0000000

Speed_50MHz = 0x80000C0

PuPd__UP      = 0x4000100

When I use SPI2_Init to initialize only PB13 the four registers are:

Mode_AF        = 0x0000280

OType_PP      = 0x0000280

Speed_50MHz = 0x8000280

PuPd__UP      = 0x4000280

When I first initialize PB13 as an output port and then use SPI2_Init to re-initialize it the four registers are:

Mode_AF        = 0x8000280

OType_PP      = 0x0000000

Speed_50MHz = 0x80000C0

PuPd__UP      = 0x4000100

After the last configuration there is a clock signal on PB13 when I call SPI2_Send_Data. 

I started stepping through GPIO_Init and this is what I found.

In all cases the values passed into GPIO_Init, which are in Regesters 0x2001E7C, 7D, 7E and 7F, are correct. They are: 7C (Mode) = 0x01 or 0x02, 7D (Speed) = 0x02, 7E (Type) = 0x00, 7F (PuPd) = 0x01.

When PB13 is set up as a Port and currentpin = pos in Speed Mode Configuration R5 = 0x02, which is the correct value, and 0x02 is loaded into into GPIOx->OSPEEDR. But when only SPI2 initializes PB13 in Speed Mode Configuration R5 is 0x280 and 0x280 is loaded into GPIOx->OSPEEDR. Not sure why this is happening. It has been many years since I’ve worked with assembly, so this is slow going.

I did remove the second  RCC_APB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);

Bob

Chris1
Senior III

You have: RCC_APB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);

but GPIOs are actually on AHB1 bus.

Try: RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);

(As JW pointed out already).

BRowl
Associate II

Thanks so much Chris, that solved it. I was sure it must be something simple, but just couldn’t see what.