Forum: Mikrocontroller und Digitale Elektronik STM32F03C8: SD-Card antwortet nicht


von Harald (Gast)


Lesenswert?

Wenn ich das Kommando CMD0 zum Aktivieren des SPI-Modus sende, kommen 
Clock und Daten bei der SD-Card an. CS ist auf Low. Nur es kommt keine 
Antwort von der Karte.

Meine Vermutung ist, dass etwas mit der Initialisierung (siehe unten) 
nicht stimmt.

Kann mal jemand drüber schauen?
1
void resetspi (void)
2
{
3
  GPIO_InitTypeDef GPIO_InitStructure;
4
  SPI_InitTypeDef SPI_InitStructure;
5
6
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_SPI1, ENABLE);
7
8
  // SPI1: SCK and MOSI 
9
  GPIO_InitStructure.GPIO_Pin     = GPIO_Pin_5 | GPIO_Pin_7;
10
  GPIO_InitStructure.GPIO_Speed   = GPIO_Speed_50MHz;
11
  GPIO_InitStructure.GPIO_Mode     = GPIO_Mode_AF_PP;
12
  GPIO_Init(GPIOA, &GPIO_InitStructure);
13
  
14
  // SPI1: NSS
15
  GPIO_InitStructure.GPIO_Pin     = GPIO_Pin_4;
16
  GPIO_InitStructure.GPIO_Speed   = GPIO_Speed_50MHz;
17
  GPIO_InitStructure.GPIO_Mode     = GPIO_Mode_Out_PP;
18
  GPIO_Init(GPIOA, &GPIO_InitStructure);
19
20
  
21
  // SPI: MISO
22
  GPIO_InitStructure.GPIO_Pin     = GPIO_Pin_6;
23
  GPIO_InitStructure.GPIO_Speed   = GPIO_Speed_50MHz;
24
  GPIO_InitStructure.GPIO_Mode     = GPIO_Mode_IN_FLOATING;
25
  GPIO_Init(GPIOA, &GPIO_InitStructure);
26
27
  /* SPI1 configuration ------------------------------------------------------*/
28
  SPI_InitStructure.SPI_Direction       = SPI_Direction_2Lines_FullDuplex;
29
  SPI_InitStructure.SPI_Mode           = SPI_Mode_Master;
30
  SPI_InitStructure.SPI_DataSize        = SPI_DataSize_8b;
31
  SPI_InitStructure.SPI_CPOL          = SPI_CPOL_Low;     // SD-Card: CPOL = 0, CPHA = 0 ... oder 
32
  SPI_InitStructure.SPI_CPHA            = SPI_CPHA_2Edge;    // ... CPOL = 1, CPHA = 1
33
  SPI_InitStructure.SPI_NSS             = SPI_NSS_Soft;
34
  SPI_InitStructure.SPI_BaudRatePrescaler   = SPI_BaudRatePrescaler_32;
35
  SPI_InitStructure.SPI_FirstBit       = SPI_FirstBit_MSB;
36
  SPI_InitStructure.SPI_CRCPolynomial    = 7;
37
  SPI_Init(SPI1, &SPI_InitStructure);
38
39
  SPI_Cmd(SPI1, ENABLE);
40
}

von Harald (Gast)


Angehängte Dateien:

Lesenswert?

Im Anhang die Signale Clock und MOSI (CRC-Byte[0x95] des Kommandos 
CMD0), die die Karte empfängt. Der Datenausgang der Karte (mit 
verschiedenen Karten getestet) bleibt permanent auf High.

Wer hat eine Idee, wonach ich suchen muss?

von Juergen G. (jup)


Angehängte Dateien:

Lesenswert?

Welche PerphLib verwendest Du denn?

Ich habe das aus den STM Quellen uebernommen und dann ein wenig 
angepasst.

Ich weiss nicht wie in Deiner PerphLib

GPIO_Mode_AF_PP
GPIO_Mode_IN_FLOATING

definiert sind

aber ich meine Du solltest die alternativ functionen an MOSI und MISO 
aktivieren.

von Juergen G. (jup)


Lesenswert?

BTW in meinem Code ist nur die GPIO config fuer Dich relevant.

ab der Funktion

SPI_I2S_DeInit(SPIx );

in meinem Code

kannst Du Deinen Code verwenden.

von Harald (Gast)


Angehängte Dateien:

Lesenswert?

Juergen G. schrieb:

Vielen Dank für deinen Code.

> Welche PerphLib verwendest Du denn?

Die Library von ST.

> Ich weiss nicht wie in Deiner PerphLib

> GPIO_Mode_AF_PP
> GPIO_Mode_IN_FLOATING

GPIO_Mode_AF_PP ist     Alternate Function Push-Pull
GPIO_Mode_IN_FLOATING   normaler GPIO-Input floatend

Einen "Alternate Function Mode" für Inputs gibt es nicht.

--------------------------------------------------------------------

Bin jetzt weiter gekommen. Die Karte antwortet auf das CMD0-Kommando, 
allerdings mit 0x80, was ja nicht richtig ist (siehe Anhang). Erwarten 
würde ich 0x01.

von Juergen G. (jup)


Lesenswert?

Die Pins nur als Eingang/Ausgang mit was auch immer fuer Gimmicks zu 
configurieren reicht nicht.

mir fehlt die GPIO_PinAFConfig in Deinem Code.

Das Datenblatt zu Deinem Controller sagt, dass SPI an PA5 PA6 PA7 
Alternativ Function AF0 ist.
So musst Du die auch Configurieren, sonst weiss der uC nicht, dass er 
die Pins ans SPI mappen soll.

von Harald (Gast)


Angehängte Dateien:

Lesenswert?

Juergen G. schrieb:

> mir fehlt die GPIO_PinAFConfig in Deinem Code.

So eine Funktion o. ä. finde ich in der ST-Library nicht.

> Das Datenblatt zu Deinem Controller sagt, dass SPI an PA5 PA6 PA7
> Alternativ Function AF0 ist.
> So musst Du die auch Configurieren, sonst weiss der uC nicht, dass er
> die Pins ans SPI mappen soll.

Im Anhang ist ein Bild der Portstruktur und eins mit den 
Konfigurationsmöglichkeiten des STM32F103C8.

Aus denen entnahm ich, dass ein "normaler" Input-Pin immer mit dem 
"Alternate Function Input" verbunden ist.

von Harald (Gast)


Lesenswert?

Ergänzung zu meinem Post:

Aus dem Reference Manual zum STM32F102C8:

For alternate function inputs, the port must be configured in Input mode 
(floating, pullup or pull-down) and the input pin must be driven 
externally.

For alternate function outputs, the port must be configured in Alternate 
Function Output mode (Push-Pull or Open-Drain).

For bidirectional Alternate Functions, the port bit must be configured 
in Alternate Function Output mode (Push-Pull or Open-Drain). In this 
case the input driver is configured in input floating mode

von holger (Gast)


Lesenswert?

// SPI: MISO
  GPIO_InitStructure.GPIO_Pin     = GPIO_Pin_6;
  GPIO_InitStructure.GPIO_Speed   = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode     = GPIO_Mode_IN_FLOATING;


Mach da mal Input mit Pullup draus.

von Harald (Gast)


Lesenswert?

Danke für den Tipp.

Leider keine Änderung.

von holger (Gast)


Lesenswert?

>  SPI_InitStructure.SPI_CPHA            = SPI_CPHA_2Edge;    // ... CPOL =

Bei mir geht das mit SPI_CPHA_1Edge.
Zeig mal dein SD Init. Mit der SPI Init alleine kann man nichts 
anfangen.

von Harald (Gast)


Angehängte Dateien:

Lesenswert?

holger schrieb:

>>  SPI_InitStructure.SPI_CPHA            = SPI_CPHA_2Edge;    // ... CPOL =
>
> Bei mir geht das mit SPI_CPHA_1Edge.

Es sieht sieht aus, dass das das Problem löst. Vielen Dank!

Anhang: Antwort aus das CMD0-Kommando (0x01).
Clock: gelb
MISO: blau

von Juergen G. (jup)


Lesenswert?

In Figure 13 des von Dir angehaengten Documents sieht man ganz unten 
links einen Pfeil an dem steht "from on-chip peripheral"
da haengt der Mux dran, der den Port auf die verschiedenen Peripherien 
mapped.

http://www.st.com/st-web-ui/static/active/en/resource/technical/document/datasheet/DM00088500.pdf

Tabelle Seite 31
sieht man das PA5 nur eine AF hat
PA6 und PA7 mehrere.

aktuelle stdperphlib V1.1.0 Download from
http://www.st.com/web/en/catalog/tools/PF257884

im File

Libraries/STM32F0xx_StdPeriph_Driver/inc/stm32f0xx_gpio.h

Zeile 335 die deklaration

und
Libraries/STM32F0xx_StdPeriph_Driver/src/stm32f0xx_gpio.c

Zeile 445ff die Beschreibung und Implementation der Function

GPIO_PinAFConfig

da sieht man auch, das bei den Parametern ein

@arg GPIO_AF_0:WKUP, EVENTOUT, TIM15, SPI1, TIM17,MCO, SWDAT, SWCLK, 
TIM14,
 *                    BOOT,USART1, CEC, IR_OUT, SPI2

existiert, der SPI1 enthaelt.

Das was Du aufgefuehrt hast ist die Port-config, das hast Du ja schon 
richtig gemacht.
GPIO_PinAFConfig mapped aber die Peripherie auf den Portpin.
Wenn Du diese Function nicht aufrufst, schreibt der SPI einfach auf den
Datenbus und das verhalten ist undefiniert.

PA5 hat nur eine AF, da kann nichts schief gehen und Der Clock geht raus 
wo er soll.
PA6 und PA7 haben mehrere AF's, da ist es ungewiss wo das hingeht.

: Bearbeitet durch User
von Harald (Gast)


Angehängte Dateien:

Lesenswert?

Juergen G. schrieb:

> PA5 hat nur eine AF, da kann nichts schief gehen und Der Clock geht raus
> wo er soll.
> PA6 und PA7 haben mehrere AF's, da ist es ungewiss wo das hingeht.

Es geht zu allen AFs des 48-Pin STM32F103C8. Die Auswahl erfolgt über 
die Clock der einzelnen Module. Deshalb funktioniert die Konfiguration 
(siehe Anhang aus dem REF-Manual).

von Juergen G. (jup)


Lesenswert?

Was hast Du denn nun fuer einen Chip, einen STM32F03C8 wie im Topic 
steht, der bei ST allerdings STM32F030C8 heisst

einen STM32F102C8 wie hier steht
Harald schrieb:
> Aus dem Reference Manual zum STM32F102C8:


oder einen STM32F103
wie in Deinem letzten Post
Harald schrieb:
> STM32F103C8

Da gibts ein paar Unterschiede und Du kannst nicht einfach die RefMan's 
nehmen wie es Dir gerade passt.


Ausserdem hab Dir doch schon bestaetigt, dass Deine GPIO Config richtig 
ist.

Wovon ich rede ist der map (interne "virtuelle Verdrahtung") der 
Peripherie SPI mit dem GPIO.

Wenn die SPI Peripherie einfach irgendwohin schreibt dann kommt das auch 
irgendwo an. Doch kannst Du nicht erwarten das das da und nur da ankommt 
wo Du es haben willst.

von Juergen G. (jup)


Lesenswert?

Harald schrieb:
> Es geht zu allen AFs des 48-Pin STM32F103C8. Die Auswahl erfolgt über
> die Clock der einzelnen Module. Deshalb funktioniert die Konfiguration
> (siehe Anhang aus dem REF-Manual).

Die AF's und die Clock haben nichts miteinander zu tun.
Mit der Clock schaltest Du die Clock auf die Peripherie womit diese 
aktiviert wird.

von Harald (Gast)


Lesenswert?

Juergen G. schrieb:
> Harald schrieb:
>> Es geht zu allen AFs des 48-Pin STM32F103C8. Die Auswahl erfolgt über
>> die Clock der einzelnen Module. Deshalb funktioniert die Konfiguration
>> (siehe Anhang aus dem REF-Manual).
>
> Die AF's und die Clock haben nichts miteinander zu tun.
> Mit der Clock schaltest Du die Clock auf die Peripherie womit diese
> aktiviert wird.

Die AFs und die Clock haben etwas mit einander zu tun.

Zitat (Datenblatt zum STM32F103C8):

If several peripherals share the same I/O pin, to avoid conflict between 
these alternate functions only one peripheral should be enabled at a 
time through the peripheral clock enable bit (in the corresponding RCC 
peripheral clock enable register).

von Juergen G. (jup)


Lesenswert?

Ist Dir bei meiner Frage nach dem wirklich von Dir verwendeten 
Controller kein Licht aufgegangen?

Wir reden hier von verschiedenen Controllern.

Bei den aelteren Chips hat man das so gemacht (machen muessen), das man 
bei einem Pin der mit mehr als einer Peripherie betrieben wurde die 
Peripherie-Clock der gerade nicht benutzten Peripherie abschalten musste 
um keinen Datensalat auf den Pin zu bekommen.
Also die entsprechende Clock der Peripherie schon Einfluss auf die 
Funktion des GPIO hatte.
Es war aber immer die bessere Wahl nur eine Peripherie an einem Pin zu 
betreiben, weil es vielfach zu unerwuenschten Ereignissen kam.

Die neueren Chips haben da einen eigenen Multiplexer vor jedem GPIO, mit 
dem man die entsprechende Peripherie auf den Pin aufschalten kann ohne 
die Peripherie anhalten zu muessen.

von Harald (Gast)


Lesenswert?

Juergen G. schrieb:

> Ist Dir bei meiner Frage nach dem wirklich von Dir verwendeten
> Controller kein Licht aufgegangen?

Nein. Das liegt daran, dass du hier im Forum die Lampe mit der 
geringsten Beleuchtungsstärke bist.

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.