Forum: Mikrocontroller und Digitale Elektronik STM32F04 als Slave - Wie Frame lesen?


von mr. mo (Gast)


Angehängte Dateien:

Lesenswert?

Guten Abend zusammen,

folgendes Szenario: An einem STM32F04 (Slave) ist am SPI1 ein Arduino 
(Master) angeschlossen welcher mir 4 Bytes schickt, dieses Frame ist mit 
einem CS umschlossen. (Siehe Anhang)

Ich habe es nicht geschafft diese 4 Bytes 'a' 'b' 'c' 'd' korrekt zu 
empfangen. Ich empfange immer zufällige Daten. Den SPI-Mode habe ich 
mehrere Male überprüft, das sollte passen.

Verbunden wie folgt:
1
    Arduino Nano:    STM32F04:
2
SCK    13          PB3
3
MOSI   11          PB5
4
CS     10          PA15

Folgendes hatte ich versucht:
1. Per RXNE Interrupt auf ankommende Daten reagieren:
Der RXNE Interrupt hat regelmäßig ausgelöst auch wenn keine Daten 
geschickt wurden. Immer im Interval von rund 40µs (mit Logic Analayzer 
geprüft). Die 4 gelesenen Bytes waren immer zufällig.

2. Per External Interrupt auf Fallende Flanke des CS reagieren:
Ich habe versucht im Interrupt-Handler die vier Bytes zu lesen. Es 
scheint dann aber nichts im Datenregister zu liegen, er bleibt immer in 
der Schleife hängen.
1
extern "C" void EXTI15_10_IRQHandler(void)
2
{
3
  static uint8_t byte;
4
  if (EXTI_GetITStatus(EXTI_Line15) == SET)
5
  {
6
    GPIO_SetBits(GPIOA, GPIO_Pin_0);  // Fuer Logic Analyzer
7
8
    // Lese die vier Bytes
9
    for (int i = 0; i < 4; ++i)
10
    {
11
      while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET);
12
      byte = SPI_I2S_ReceiveData(SPI1);
13
    }
14
15
    EXTI_ClearITPendingBit(EXTI_Line15);
16
    GPIO_ResetBits(GPIOA, GPIO_Pin_0);  // Fuer Logic Analyzer
17
  }
18
}

Konfiguriert habe ich SPI1 wie folgt (hier mit External Interrupt):
1
void init_SPI1(void) {
2
3
    GPIO_InitTypeDef GPIO_InitStruct;
4
  NVIC_InitTypeDef NVIC_InitStructure;
5
  EXTI_InitTypeDef EXTI_InitStruct;
6
  SPI_InitTypeDef SPI_InitStruct;
7
8
  // Clocks
9
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
10
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
11
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);
12
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
13
  
14
  // GPIO
15
  GPIO_PinAFConfig(GPIOB, GPIO_PinSource3, GPIO_AF_SPI1);
16
  GPIO_PinAFConfig(GPIOB, GPIO_PinSource4, GPIO_AF_SPI1);
17
  GPIO_PinAFConfig(GPIOB, GPIO_PinSource5, GPIO_AF_SPI1);
18
19
  GPIO_InitStruct.GPIO_Pin = GPIO_Pin_3 | GPIO_Pin_5;
20
  GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
21
  GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
22
  GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
23
  GPIO_Init(GPIOB, &GPIO_InitStruct);
24
  
25
  // Chip select
26
  GPIO_InitStruct.GPIO_Pin = GPIO_Pin_15;
27
  GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN;
28
  GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;
29
  GPIO_InitStruct.GPIO_Speed = GPIO_Speed_25MHz;
30
  GPIO_Init(GPIOA, &GPIO_InitStruct);
31
32
  SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA, EXTI_PinSource15);
33
34
  EXTI_InitStruct.EXTI_Line = EXTI_Line15;
35
  EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt;
36
  EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Falling;
37
  EXTI_InitStruct.EXTI_LineCmd = ENABLE;
38
  EXTI_Init(&EXTI_InitStruct);
39
40
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
41
  NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn;
42
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
43
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
44
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
45
  NVIC_Init(&NVIC_InitStructure);
46
  
47
  // SPI
48
  SPI_InitStruct.SPI_Direction = SPI_Direction_Rx;
49
  SPI_InitStruct.SPI_Mode = SPI_Mode_Slave;
50
  SPI_InitStruct.SPI_DataSize = SPI_DataSize_8b; 
51
  SPI_InitStruct.SPI_CPOL = SPI_CPOL_High;
52
  SPI_InitStruct.SPI_CPHA = SPI_CPHA_1Edge;     
53
  SPI_InitStruct.SPI_NSS = SPI_NSS_Soft | SPI_NSSInternalSoft_Reset;
54
  SPI_InitStruct.SPI_FirstBit = SPI_FirstBit_MSB;
55
  SPI_Init(SPI1, &SPI_InitStruct);
56
57
  SPI_Cmd(SPI1, ENABLE); 
58
}

Inzwischen habe ich wahrscheinlich Tomaten auf den Augen. Sieht jemand 
den Fehler? Hat jemand schon einmal den STM32 als Slave betrieben und 
nur Daten empfangen?

von mr. mo (Gast)


Lesenswert?

Sollte natürlich STM32F407 heißen, ...

von holger (Gast)


Lesenswert?

>Sieht jemand den Fehler?

Ja, lass den STM das was der Arduino macht gleich mit
erledigen. Dann sparst du dir die Datenübertragung.

SCNR:)

von mr. mo (Gast)


Lesenswert?

holger schrieb:
> Ja, lass den STM das was der Arduino macht gleich mit
> erledigen. Dann sparst du dir die Datenübertragung.

Der Arduino ist aktuell nur zum Testen gedacht. Eigentlich ist ein ADC 
angebunden der Daten über SPI an den STM feuert.

Da ich schon Probleme hatte die Daten vom ADC abzuholen, habe ich mir 
mit dem Arduino was zum Testen gebastelt um die SPI Hardware als Slave 
in Betrieb zu nehmen.

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.