Forum: Mikrocontroller und Digitale Elektronik SPI MISO auf High


von Uwe (Gast)


Lesenswert?

Nabend,

ich versuche gerade an meinem STM32F4 Discovery-Board (Master) die SPI1 
Schnittstelle in Betrieb zu nehmen, mit folgendem Intit:
1
  // enable clock for used IO pins
2
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
3
  
4
  /* configure pins used by SPI1
5
   * PA5 = SCK
6
   * PA6 = MISO
7
   * PA7 = MOSI
8
   */
9
  GPIO_InitStruct.GPIO_Pin = GPIO_Pin_7 | GPIO_Pin_6 | GPIO_Pin_5;
10
  GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
11
  GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
12
  GPIO_InitStruct.GPIO_Speed = GPIO_Speed_100MHz;
13
  GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
14
  GPIO_Init(GPIOA, &GPIO_InitStruct);
15
  
16
  // connect SPI1 pins to SPI alternate function
17
  GPIO_PinAFConfig(GPIOA, GPIO_PinSource5, GPIO_AF_SPI1);
18
  GPIO_PinAFConfig(GPIOA, GPIO_PinSource6, GPIO_AF_SPI1);
19
  GPIO_PinAFConfig(GPIOA, GPIO_PinSource7, GPIO_AF_SPI1);
20
21
SPI_InitStruct.SPI_Direction = SPI_Direction_2Lines_FullDuplex; 
22
SPI_InitStruct.SPI_Mode = SPI_Mode_Master;     
23
SPI_InitStruct.SPI_DataSize = SPI_DataSize_8b; 
24
SPI_InitStruct.SPI_CPOL = SPI_CPOL_Low;        
25
SPI_InitStruct.SPI_CPHA = SPI_CPHA_1Edge;      
26
SPI_InitStruct.SPI_NSS = SPI_NSS_Soft | SPI_NSSInternalSoft_Set;
27
SPI_InitStruct.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4; 
28
SPI_InitStruct.SPI_FirstBit = SPI_FirstBit_MSB;
29
SPI_Init(SPI1, &SPI_InitStruct); 
30
  
31
SPI_Cmd(SPI1, ENABLE); // enable SPI1

SCK und MOSI haben beim Senden die erwarteten Signale(mit Oszi 
gemessen).
Nur das Empfangen bereitet noch Probleme. Dabei ist mir aufgefallen dass 
der MISO-Pin High Potential hat, obwohl er ja eigentlich Eingang ist. 
Hat jemand eine Idee wie der MISO Pin korrekt als Eingang konfiguriert 
wird?

Grüsse
Uwe

von Gerhard G. (g_g)


Lesenswert?

Hallo,

du hast vermutlich eine Doppelbelegung (LIS302DL siehe Board)

SPI1 ist hier schon belegt.

Nimm mal einen freien SPI-Port zum Testen


Gruß G.G.

von Uwe (Gast)


Lesenswert?

Hallo Gerhard,

erstmal danke für deine Antwort.

Soll das also heißen, dass ein Ausgang des MEMS(LIS302DL) fest mit dem
PA6 (MISO) verdrahtet ist und dem Eingang PA6 (welcher, wie oben 
beschrieben, richtig als Eingang konfiguriert ist) ein High liefert.

D.h. also daß das High nicht vom PA6(MISO) kommt, sondern vom 
LIS302DL!???



Gruss
Uwe

von Gerhard G. (g_g)


Angehängte Dateien:

Lesenswert?

Hallo Uwe,


du solltest dir dringend das

UM1472 User Manual STM32F4DISCOVERY
STM32F4 high-performance discovery board

anschauen.



Gruß G.G.

von Michi (Gast)


Lesenswert?

Ist PE3 high? Das ist der CS Pin vom LIS3DSH. Damit ist der störende Pin 
am LIS3DSH nicht mehr Ausgang sondern Eingang und es sollte gehen.

von Chris M. (ch_meier)


Lesenswert?

Hi,

Habe das selbe Problem, aber erstmal zu deinem Code.
@Uwe
Falls das immer noch aktuell ist, glaube ich hast du die CPOL und CPHA 
nicht richtig gesetzt, wenn ich das Datenblatt des LIS302DL richtig 
gelesen habe:
SPC is the Serial Port Clock and it is
controlled by the SPI master. It is stopped high when CS is high (no 
transmission). SDI and
SDO are respectively the Serial Port Data Input and Output. Those lines 
are driven at the
falling edge of SPC and should be captured at the rising edge of SPC.

Zu meinem Problem, falls jemand eine Lösung hat:
Mein Quelltext ist ziemlich genau gleich wie der von Uwe. Mein main.c 
sieht so aus:
1
int main(void)
2
{
3
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
4
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
5
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE);
6
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
7
8
9
  GPIO_InitTypeDef GPIO_InitStructure;
10
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
11
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
12
  GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
13
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
14
  GPIO_Init(GPIOE, &GPIO_InitStructure);
15
16
  GPIO_SetBits(GPIOE, GPIO_Pin_3);
17
18
  PD13_Init();
19
  TIM7_Init(64);
20
  EXTI0_Config();
21
22
  SPI_Output_Buffer[0] = (WRITE<<5 | NO_INC<<4 | 0xF);
23
  SPI_Output_Buffer[1] = 0;
24
  SPI_Output_Buffer[2] = 0;
25
26
  GPIO_ResetBits(GPIOE, GPIO_Pin_3);
27
  SPI1_Init();
28
29
    while(1)
30
    {
31
      while(countBuffer < 2)
32
      {
33
        SPI1->DR = SPI_Output_Buffer[countBuffer];
34
        countBuffer++;
35
        while(!(SPI1->SR & SPI_FLAG_TXE));
36
      }
37
      if(countBuffer > 1)
38
        GPIO_SetBits(GPIOE, GPIO_Pin_3);
39
40
      if(StatusButton)
41
        GPIO_SetBits(GPIOD, GPIO_Pin_13);
42
      else
43
        GPIO_ResetBits(GPIOD, GPIO_Pin_13);
44
    }
45
}

Die SPI1_Init():
1
void SPI1_Init(void)
2
{
3
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);
4
5
  GPIO_InitTypeDef   GPIO_InitStructure;
6
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
7
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
8
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
9
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
10
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
11
  GPIO_Init(GPIOA, &GPIO_InitStructure);
12
  GPIO_PinAFConfig(GPIOA, GPIO_PinSource5, GPIO_AF_SPI1);
13
  GPIO_PinAFConfig(GPIOA, GPIO_PinSource6, GPIO_AF_SPI1);
14
  GPIO_PinAFConfig(GPIOA, GPIO_PinSource7, GPIO_AF_SPI1);
15
16
  SPI_InitTypeDef SPI_InitStructure;
17
  SPI_StructInit(&SPI_InitStructure);
18
  SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
19
  SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;
20
  SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
21
  SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
22
  SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
23
  SPI_Init(SPI1, &SPI_InitStructure);
24
25
  NVIC_InitTypeDef   NVIC_InitStructure;
26
  NVIC_InitStructure.NVIC_IRQChannel = SPI1_IRQn;
27
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0A;
28
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0A;
29
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
30
  NVIC_Init(&NVIC_InitStructure);
31
32
  SPI1->CR2 |= SPI_CR2_RXNEIE;// | SPI_CR2_TXEIE;
33
  SPI1->CR1 |= SPI_CR1_CPOL | SPI_CR1_CPHA;
34
35
  //SPI_Cmd(SPI1, ENABLE);
36
  SPI1->CR1 |= SPI_CR1_SSM | SPI_CR1_SSI;
37
  SPI1->CR1 |= SPI_CR1_MSTR;
38
  SPI1->CR1 |= SPI_CR1_SPE;
39
}

Die ISR:
1
void SPI1_IRQHandler(void)
2
{
3
    SPI_Input_Buffer[countBuffer_2] = SPI1->DR;
4
    countBuffer_2++;
5
6
}

Hat jemand eine Idee, warum ich immer 255 aus dem DR auslese? Habe 
leider kein Oszilloskop um die Datenübertragung zum MEMS nachzuprüfen, 
deshalb die Frage im Forum. Das gesendete Kommando zum auslesen des 
Who_am_i registers ist 000 1111 (=0x0F).

Vielen Dank im Voraus

von Uwe (Gast)


Lesenswert?

Hallo Chris,

habs mit SPI2 und SPI3 ausprobiert und es hat problemlos funktioniert 
(mit SPI_CPOL_Low und SPI_CPHA_1Edge)!
Ich denke mal wenn man PE3 auf high setzt ((SPI1) CS Pin vom LIS3DSH) 
müsste es auch gehen!
Welchen Takt bzw. Flankensteilheit hat dein SCK und wie sieht deine 
"Masseführung" aus. Hatte am Anfang auch auch seltsame Werte im DR bis 
ich Masse parallel zur Taktleitung verlegt hatte.


Gruss
Uwe

von Chris M. (ch_meier)


Angehängte Dateien:

Lesenswert?

Hi Uwe,

Ich nutze das Discovery Board vom STM32F407, bei dem der LIS302DL direkt 
auf dem SPI1 angeschlossen ist, also nur mit dem SPI1 angesprochen 
werden kann. Über die Masseleitung kann ich leider nix sagen, denke aber 
die sollte einwandfrei sein.
Die Flankensteilheit kann ich erst Montag messen, habe vorher kein 
Oszilloskop zur Hand. Aber du hast mir schonmal geholfen damit, dass du 
es mit CPOL=0 und CPHA=0 zum Laufen gebracht hast. Aber beim CS Pin 
meinste schon auf Low setzen, richtig?
Hab mal ein Bild vom Datenblatt angehängt wo die SPI Kommunikation im 
Zeitbereich aufgezeichnet ist. Unter dem Diagramm steht nämlich 
explizit, dass der SCK High sein soll, wenn nix gesendet wird. Außerdem 
wird beschrieben, dass bei fallender Flanke geschrieben, bei steigender 
übernommen werden soll....

von holger (Gast)


Lesenswert?

>Ich nutze das Discovery Board vom STM32F407, bei dem der LIS302DL direkt
>auf dem SPI1 angeschlossen ist

Dann kannst du doch ganz einfach mal in den Code
zur Demofirmware reinschauen wie es gemacht wird.

von Uwe (Gast)


Lesenswert?

Hallo Chris,

ich wollte an SPI1 einen seriellen Speicher anschliessen ohne den 
LIS302DL zu nutzen. Deshalb auch CS(PE3) auf High in meinen Fall.

siehe Hinweis von Michi:

Michi schrieb:
> Ist PE3 high? Das ist der CS Pin vom LIS3DSH. Damit ist der
> störende Pin
> am LIS3DSH nicht mehr Ausgang sondern Eingang und es sollte gehen.

Kleines Missverständnis, also sorry!

Gruss
Uwe

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.