STM32F10x SPI - Keine Uhr

Ich versuche, den grundlegenden SPI-Betrieb auf einem STM32F107VC-Chip mit dem WaveShare Port107-Entwicklungsboard zum Laufen zu bringen. Ich versuche, SPI1 zu initialisieren, das sich auf PA4-PA7 befindet.
Ich versuche einen einfachen Loopback-Test, also ist MISO direkt mit MOSI verbunden. Ich habe auch ein Oszilloskop an NSS und SCK angeschlossen.

Unten ist mein Code:

// Clock configuration
RCC->APB2ENR |= 1;              // Alternate Function Clock Enable
RCC->APB2ENR |= 1<<2;           // Enable clock to Port A.
RCC->APB2ENR |= 1<<12;          // Enable clock for SPI1.

// Pin configuration (no remapping)
// Output = AF PushPull 50MHz. 
// Input = Active Pullup/Pulldown
// I have tried NSS as AFPuP, Active Pullup/Pulldown, GPIO output etc...
// NSS (PA4) = input, CLK (PA5) = output, MISO (PA6) = input, MOSI (PA7) = output
GPIOA->CRL = 0xB8B80000;

// General SPI configuration
SPI1->CR1 = 0;
SPI1->CR1 |= 7<<3;                  // Lowest frequency.    
SPI1->CR1 &= ~(1<<0);               // Clock phase. 1st clock transition starts data capture
SPI1->CR1 |= 1<<1;                  // Clock polarity. High when idle.
SPI1->CR1 &= ~(1<<11);              // Use 8 bit data
SPI1->CR1 |= 1<<7;                  // LSB transmitted first.
//SPI1->CR1 |= 1<<9;                // Software slave management
//SPI1->CR1 |= 1<<8                 // Software NSS bit high
SPI1->CR1 |= 1<<2;                  // Master device.
SPI1->CR1 &= ~(1<<10);              // Use both RX and TX
SPI1->CR1 &= ~(3<<12);              // No CRC
SPI1->CR1 &= ~(1<<15);              // 2-line unidirectional mode
SPI1->CR2 = 0;                      // Polling mode (no interrupts)
SPI1->CR1 |= 1<<6;                  // Enable SPI1.

Um nun den Loopback-Test durchzuführen, sende ich ein Byte und lese dann das Byte zurück (ich habe die Verwendung eines 8-Bit-Schieberegisters konfiguriert).

void loopback(unsigned char byte)
{
    GPIOA->BSRR &= ~(1<<4); // !NSS line set to low (active) state. I have
                            // also attempted to use GPIOA->ODR and
                            // also attempted software NSS mode.
    //  while ((SPI1->SR & (1 << 7)) != 0 );    // Wait for BUSY to clear. not using.
    while (!(SPI1->SR & (1 << 1))); // Wait TXE (Transmit buffer empty)
    SPI1->DR = byte;

    // read it back
    unsigned char readByte = ReadByte();

    if (byte == readByte)
    {
         // ... Test passed!
    }
    GPIOA->BSRR |= 1<<4;     //!NSS set high. (unactive state).
}

unsigned char ReadByte(void)
{
    while (!(SPI1->SR & (1 << 0))); // Wait RXNE (Receive not empty (we have data))
    unsigned char readByte = SPI1->DR;
    return readByte;
}

Überwachen von CLK und NSS (und MISO/MOSI) mit einem Oszilloskop, wenn NSS in seinen aktiven Low-Zustand geht, oszilliert keine Taktleitung. Selbst wenn eine Übertragung versucht wird, werden die Bits im Datenregister gesetzt, aber ich glaube nicht, dass sie aus DR herausgeschoben werden, da RXNE niemals hoch geht (was sinnvoll ist, da keine Taktleitung aktiv ist).

Könnte mir jemand sagen, warum die clk-Leitung niemals oszilliert? Ist meine Konfig falsch?

Grüße

Ihre Konfigurationen sind sehr schwer zu lesen. Warum benutzt du nicht die Standard Peripherals Library ? In den Quelldateien sollten einige gute Beschreibungen zum Einrichten vorhanden sein.
Ihre Konfigurationen sind leicht lesbar, da sie nicht Dinge verdecken, wie es die Bibliotheksfunktionen tun. Die Verwendung von Aliasnamen für Bitnummern würde jedoch die Lesbarkeit und Portabilität verbessern.
Warum ist NSS als Eingabe konfiguriert?
@venny Ich habe NSS sowohl als Eingang als auch als AF-Push-Pull-Ausgang konfiguriert, beide Konfigurationen haben nicht funktioniert.
Ich werde auch Aliasing für Pin-Nummern verwenden, danke für den Tipp

Antworten (1)

Entkommentieren Sie Zeilen, die SSM (CR1 Bit 9) ermöglichen, die manuelle Slave-Auswahl zu verwenden.

SPI1->CR1 |= SPI_CR1_SSM; //disable automatic SS
Wenn ich nichts in den Puffer schreibe und NSS niedrig halte, wird der CLK oszillieren?
Nein, wenn der automatische Modus nicht verwendet wird, ist NSS völlig unabhängig und nur für den empfangenden Slave nützlich. Der CLK oszilliert nur, um eine vordefinierte Anzahl von Bits herauszuschieben, nachdem ein Wert in das Sendedatenregister geschrieben wurde.