Forum: Mikrocontroller und Digitale Elektronik Initialisierung SPI STM32


von Ro B. (robret)


Lesenswert?

Hallo,
ich habe ein Problem mit der Initialisierung der SPI vom stm32f100rb.
Irgendwo in der init_SPI1 muss ein fehler sein, bzw ich vermute ich habe 
noch irgend etwas vergessen. Ich kann beim senden weder einen Takt am 
SCK pin, noch irgendwelche Flanken wechsel an einem anderen pin messen. 
Vielleich kann mir jemand sagen, was noch fehlt.
( möchte gern auf die vorgefertigten Funktionen von STM verzichten...)

Die SPI habe ich wie folgt initialisiert:

void init_SPI1(void) {

RCC->APB2ENR   |= 0x00000005; // enable clock for GPIOA + AFIO
GPIOA->CRL |= 0x000A0000;      // NSS (PB4) alternate output push-pull
GPIOA->CRL     |= 0x00600000;  // SCK (PB5) alternate output push-pull,
GPIOA->CRL     |= 0x04000000;  // MISO (PB6) input floating
GPIOA->CRL     |= 0xA0000000;  // MOSI (PB7) alternate output push-pull
AFIO->MAPR     &= 0xFFFFFFFE   // SPI1 remap löschen
AFIO->MAPR     |= 0x02000000;  // JTAG ausschalten
RCC->APB2ENR   |= 0x00001000;  // SPI1 clock anschalten
SPI1->CR1      |= 0x00000002;  // clock polarity
SPI1->CR1      |= 0x00000004;  // konfiguriert als Master
SPI1->CR1      |= 0x00000800;  // Framelänge 16Bit
SPI1->CR2      |= 0x00000004;  // SS Ausgang einschalten
SPI1->CR1      |= 0x00000040;  // SPI anschalten
}

zu test zwecken sende ich mit folgender Funktion zyklisch in der 
main()...

void transmit_SPI1(uint16_t message) {

    while(SPI1->SR & 0x00000080 != FALSE);      //== 1<<BSY

    SPI1->DR         = message;

}

von Ro bret (Gast)


Lesenswert?

Kann mir wirklich keiner weiterhelfen?

von Arne (Gast)


Lesenswert?

GPIOA->CRL |= 0x000A0000;      // NSS (PB4) alternate output push-pull
GPIOA->CRL     |= 0x00600000;  // SCK (PB5) alternate output push-pull,
GPIOA->CRL     |= 0x04000000;  // MISO (PB6) input floating
GPIOA->CRL     |= 0xA0000000;  // MOSI (PB7) alternate output push-pull

1. der Kommentar lügt: GPIOA <-> PBx
2. 0xA = 0b1010
   0x6 = 0b0110
   beide Bitmuster sollen aber auf AF PP schalten?
3. AF-PP ist nach meiner Doku 0b1011 = 0xB

von Ro bret (Gast)


Lesenswert?

Sorry, der Kommentar ist veraltet....
Der SCK ist mittlerweile auch angepasst...

GPIOA->CRL     |= 0x00900000;

Hat aber noch nicht den gewünschten effekt erbracht.


-->AF-PP kann doch 0xA oder 0xB sein...die letzten beiden Bits 
definieren doch nur die Maximal Frequenz...und die 50MHz werden meiner 
meinung nach nicht benötigt, 10MHz reichen aus....da die Höchste 
Frequenz, der SCK 4 MHz beträgt.

von Ro bret (Gast)


Lesenswert?

Ich nutze im moment auch SPI1... deshalb müsste im Kommentar auch Port A 
stehen..

von Arne S. (Gast)


Lesenswert?

Ich würde alle Output-Pins für SPI mit der selben "output-speed" 
initialisieren.
GPIOA->CRL     |= 0x000A0000;  // NSS (PB4) alternate output push-pull
GPIOA->CRL     |= 0x00A00000;  // SCK (PB5) alternate output push-pull,
GPIOA->CRL     |= 0x04000000;  // MISO (PB6) input floating
GPIOA->CRL     |= 0xA0000000;  // MOSI (PB7) alternate output push-pull

Wobei ich allerdings NSS nicht nutze, sondern mein eigenes /CS.

Das hier:
SPI1->CR1      |= 0x00000040;  // SPI anschalten

mache ich allerdings direkt nach
RCC->APB2ENR   |= 0x00000005; // enable clock for GPIOA + AFIO

Ist bei den Registern sichergestellt, dass sie zum Zeitpunkt der "|=" 
Operationen 0 sind, bzw. Veroderungen nicht zu unerwünschten Ergebnissen 
führen?
-> GPIOA->CRL  = 0x10000000 (ist-Zustand)
   GPIOA->CRL |= 0xA0000000; (ergibt 0xB0000000)

von Arne S. (Gast)


Lesenswert?

Muss heißen:
"mache ich allerdings direkt nach
RCC->APB2ENR   |= 0x00001000;  // SPI1 clock anschalten
"

von Ro bret (Gast)


Lesenswert?

Kannst du mir deinen Code für die initialisierung eventuell zur 
Verfügungstellen?
Ich finde meinen Fehler nicht. Ich nutze jetzt wie von dir beschrieben 
ein eigenes CS, kann aber selbst dann an den ausgängen nichts messen.

von Arne (Gast)


Lesenswert?

Ro bret schrieb:
> Kannst du mir deinen Code für die initialisierung eventuell zur
> Verfügungstellen?
da hätte mein Chef was dagegen.
Nimm doch ein Beispiel von STM und schau dir im Debugger Werte der 
gesetzten Register und die Reihenfolge der Initialisierung an.

von Ro bret (Gast)


Lesenswert?

Habs schon gefunden....vielen dank.
Das CRL Register hat eine Reset value von 0x44444444, das hatte ich 
nicht beachtet.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.