1
\$\begingroup\$

I am using the STM32 SPL library with an STM32F103C8 microcontroller. As part of the project, I am using the SPI1 peripheral to interface with an SD card.

Initially the SPI speed must be kept under 400 kHz for the SD card. My SPI1 initialization code is

SPI_InitTypeDef spi;

//ENABLE THE CLOCK TO SPI1 PERIPHERAL
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);

//SET SPI SPEED TO LOW SPEED MODE (~282KHZ)
spi.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;
spi.SPI_CPHA = SPI_CPHA_1Edge;
spi.SPI_CPOL = SPI_CPOL_Low;
spi.SPI_DataSize = SPI_DataSize_8b;
spi.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
spi.SPI_FirstBit = SPI_FirstBit_MSB;
spi.SPI_Mode = SPI_Mode_Master;
spi.SPI_NSS = SPI_NSS_Soft;

SPI_Init(SPI1, &spi);
SPI_Cmd(SPI1, ENABLE);

Of course, once the initial initialization of the SD card is complete, I would like to speed up the SPI1 peripheral.

I could not find any function in the SPL that would return a structure of the type SPI_InitTypeDef containing the currently configured settings of an SPI peripheral.

Does that mean I have to create a new such structure (and repeat all the configuration values even if I only wish to change the speed and keep the rest the same as already configured) and then call SPI_Init() with this new structure?

\$\endgroup\$
3
\$\begingroup\$

If you find the SPI_CR1 register in the Reference Manual, you can see that the speed is set by the BR bits (bits 5:3 in SPI_CR1). You can adjust the baud rate on the fly by changing these bits, as long as there isn't a transmission currently in progress:

enter image description here

Conveniently, the SPI_BaudRatePrescaler defines provided by the Standard Peripheral Library map directly on top of the SPI_CR1 bits.

What I do is create the following #defines:

#define BAUD_RATE_BITMASK    0xFFC7                // Used to clear CR1->BR[2:0]
#define SPI_SPEED_LOW    SPI_BaudRatePrescaler_32  // 72/32 = 2.25MHz
#define SPI_SPEED_HIGH   SPI_BaudRatePrescaler_4   // 72/4 = 18MHz

Then I use something like this to adjust the speed (where NewSpeed is one of the SPL defines):

void spiSetSpeed(uint16_t NewSpeed)
{
    // Assert the new speed setting
    SPI1->CR1 &= BAUD_RATE_BITMASK;                // Clear the BR[2:0] bits
    SPI1->CR1 = (uint16_t)(SPI1->CR1 | NewSpeed);  // Set the bits
}
\$\endgroup\$
  • \$\begingroup\$ Thanks ! I had looked this over. I guess I should have been more clear in my question that if there was a function in standard peripheral library to do this. \$\endgroup\$ – Ankit Mar 23 '16 at 5:58
  • \$\begingroup\$ @Ankit I don't believe that there is. At least, I never found one! \$\endgroup\$ – bitsmack Mar 23 '16 at 6:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.