Ich verwende die STM32 SPL-Bibliothek mit einem STM32F103C8-Mikrocontroller. Als Teil des Projekts verwende ich das SPI1-Peripheriegerät als Schnittstelle mit einer SD-Karte.
Zunächst muss die SPI-Geschwindigkeit für die SD-Karte unter 400 kHz gehalten werden. Mein SPI1-Initialisierungscode ist
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);
Natürlich möchte ich nach Abschluss der Erstinitialisierung der SD-Karte das SPI1-Peripheriegerät beschleunigen.
Ich konnte in der SPL keine Funktion finden, die eine Struktur des Typs zurückgeben würde, der SPI_InitTypeDef
die aktuell konfigurierten Einstellungen eines SPI-Peripheriegeräts enthält.
Heißt das, ich muss eine neue solche Struktur erstellen (und alle Konfigurationswerte wiederholen, auch wenn ich nur die Geschwindigkeit ändern und den Rest wie bereits konfiguriert beibehalten möchte) und dann mit SPI_Init()
dieser neuen Struktur aufrufen?
Wenn Sie das SPI_CR1-Register im Referenzhandbuch finden , können Sie sehen, dass die Geschwindigkeit durch die BR-Bits (Bits 5:3 in SPI_CR1) eingestellt wird. Sie können die Baudrate im laufenden Betrieb anpassen, indem Sie diese Bits ändern, solange gerade keine Übertragung stattfindet:
Praktischerweise werden die SPI_BaudRatePrescaler
Definitionen, die von der Standard Peripheral Library bereitgestellt werden, direkt auf den SPI_CR1-Bits abgebildet.
Ich erstelle die folgenden #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
Dann verwende ich so etwas, um die Geschwindigkeit anzupassen (wobei NewSpeed
einer der SPL definiert):
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
}
Ankit
bitsmack