STM32 SPI - RX-Problem

Gast #2824842
Lesenswert?

Hallo,

ich mache gerade erste Gehversuche mit der SPI im STM32F100RB (Discover 
Board).
Dabei habe ich beim Debuggen mit Coocox das Problem, dass beim 
SPI-Empfangen immer nur 0x00 empfangen wird. Ich habe MISO und MOSI der 
SPI1 verbunden, sodass ich eigentlich das Datenbyte empfangen sollte, 
das ich auch zum Anstoßen des Clocks verwende.

Hier mein Code:
1
/* Master Definition */
2
#define _SPI_C_
3

4
/* Includes */
5
#include "stm32f10x.h"
6
#include "spi.h"
7

8
/* Functions */
9
void SPI_Init(void)
10
{
11
  /* enable clock for SPI */
12
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);
13

14
  /* init SPI1 */
15
  SPI1->CR1 |= SPI_CR1_MSTR;
16
  SPI1->CR2 |= SPI_CR2_SSOE;
17
}
18

19
void SPI_Enable(void)
20
{
21
  SPI1->CR1 |= SPI_CR1_SPE;
22
}
23

24
void SPI_Disable(void)
25
{
26
  SPI1->CR1 &= ~SPI_CR1_SPE;
27
}
28

29
void SPI_WriteByte(uint8_t data_c)
30
{
31
  SPI1->DR = data_c;
32
  while ((SPI1->SR & SPI_SR_TXE) == 0x00);
33
}
34

35
uint8_t SPI_ReadByte(void)
36
{
37
  uint8_t result_c = (uint8_t)(SPI1->DR);
38
  SPI1->DR = 0xAA;
39
  while (((SPI1->SR) & SPI_SR_RXNE) == (uint16_t)RESET)
40
  {
41
    ;
42
  }
43

44
  result_c = (uint8_t)(SPI1->DR);
45

46
  return result_c;
47
}
48

49
#undef _SPI_C_

Die Initialisierung der entsprechenden GPIOs sieht so aus:
1
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
2

3
  /* SPI Pins on PA */
4
  GPIOA->CRL |= GPIO_CRL_MODE4_1 | GPIO_CRL_CNF4_1;
5
  GPIOA->CRL |= GPIO_CRL_MODE5_1 | GPIO_CRL_CNF5_1;
6
  GPIOA->CRL |= GPIO_CRL_CNF6_1;
7
  GPIOA->CRL |= GPIO_CRL_MODE7_1 | GPIO_CRL_CNF7_1;

Hat jemand eine Idee, woran das liegen kann?

Danke schonmal im VOrraus.
Gast #2825105
Lesenswert?

Der NSS-Pin wird durch die HW auf Masse gezogen, wenn SPI Enable gesetzt 
wird:
SPI1->CR2 |= SPI_CR2_SSOE;

(Enable wird in SPI_Enable() gesetzt)

Der CS dürfte aber auch keine Rolle spielen, wenn ich den TX- und RX- 
miteinander verbinde, also wenn sozusagen der µC an sich selbst sendet, 
oder?

Bzgl. Remapping habe ich nichts gemacht.
Gast #2825860
Lesenswert?

Thema ist gelöst:
Ich habe zum einen die Alternate Function IOs nicht mit dem Clock 
versorgt:
1
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);

Und bei der Initialisierung der GPIOA-Register habe ich die vom 
Default-Wert her gesetzten Bits nicht zurückgesetzt. Mit dieser 
Initialisierung funktioniert der Empfang:
1
/* SPI Pins on PA */
2
  GPIOA->CRL |= GPIO_CRL_MODE4_1 | GPIO_CRL_MODE4_0 | GPIO_CRL_CNF4_1;
3
  GPIOA->CRL &= ~(GPIO_CRL_CNF4_0);
4
  GPIOA->CRL |= GPIO_CRL_MODE5_1 | GPIO_CRL_MODE5_0 | GPIO_CRL_CNF5_1;
5
  GPIOA->CRL &= ~(GPIO_CRL_CNF5_0);
6
  GPIOA->CRL |= GPIO_CRL_CNF6_1;
7
  GPIOA->CRL &= ~(GPIO_CRL_MODE6_1 | GPIO_CRL_MODE6_0 | GPIO_CRL_CNF6_0);
8
  GPIOA->CRL |= GPIO_CRL_MODE7_1 | GPIO_CRL_MODE7_0 | GPIO_CRL_CNF7_1;
9
  GPIOA->CRL &= ~(GPIO_CRL_CNF7_0);
Gast #2825904
Lesenswert?

Leider gibt es bei der Komplexität moderner Controller zu viele
Fallen.

Mal "irgendwas schnell machen" klappt meistens nicht,
wenn man nicht gerade einen genau passenden Beispielcode findet.
Gast #2825997
Lesenswert?

Ja, man könnte auch die Standard Peripheral Lib benutzen, aber ich 
finde, dass man dann noch weniger Überblick hat. Außerdem will ich den 
Controller verstehen lernen und nicht fertige Code-Schnipsel zusammen 
schustern.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren