Forum: Mikrocontroller und Digitale Elektronik STM32 macht 17 Takte auf SPI


von Albert (Gast)


Angehängte Dateien:

Lesenswert?

Moin,

mit folgenden Zeilen initialisiere ich meine SPI:
1
  oSPI->CR1 = 0;
2
  oSPI->CR2 = 0;
3
  oSPI->CR2 |= (0b0111ul << 8); //8Bit
4
  oSPI->CR2 |= SPI_CR2_SSOE;
5
  oSPI->CR1 |= SPI_CR1_SSM;
6
  oSPI->CR1 |= SPI_CR1_SSI;
7
  //oSPI->CR1 |= SPI_CR1_LSBFIRST;
8
  //oSPI->CR1 |= SPI_CR1_CPHA;
9
  //oSPI->CR1 |= SPI_CR1_CPOL;
10
  oSPI->CR1 |= SPI_CR1_MSTR;
11
  oSPI->CR1 |= (6ul<<3);  //Takt durch 128 (prescaler)
12
  oSPI->CR1 |= SPI_CR1_SPE;

Wenn ich nun probeweise im Sekundentakt ein Byte raussenden möchte, sehe 
ich 17 Takte auf der SPI Leitung - egal welche Bitbreite ich in CR2 
eintrage? Warum ist das so?

Ist der Prozessor buggy? Es ist ein STM32F070.

von Albert (Gast)


Lesenswert?

Meine Sendefunktion lautet:
1
uint8_t SPI_Send(SPI_TypeDef * oSPI, uint8_t cVal){
2
  uint8_t u8Result;
3
4
  oSPI->DR = cVal;
5
  while(!(oSPI->SR & SPI_SR_RXNE));
6
  u8Result = oSPI->DR;
7
8
  return u8Result;
9
}

von A. B. (Gast)


Lesenswert?

DR ist ein 16-Bit breites Register! Daher werden mit
  oSPI->DR = cVal;
ZWEI Bytes in den TX-FIFO geschrieben. Dass cVal ein uint8_t ist, 
spielt dabei keine Rolle. Entsprechend werden mit
  u8Result = oSPI->DR;
ZWEI Bytes aus dem RX-FIFO gelesen (und das "obere" gleich wieder 
weggeworfen).

Wenn die Datenbreite beim SPI auf höchstens 8 Bit eingestellt ist, wird 
immer automatisch "gepackt", s. Fig. 254 im RM0360.

Wenn man das nicht will, muss oSPI->DR auf (uint8_t *) gecasted werden.

von Albert (Gast)


Lesenswert?

Danke für den Hinweis, aber folgender Code funktioniert leider auch 
nicht, immernoch 17 Takte:
1
uint8_t SPI_Send(SPI_TypeDef * oSPI, uint8_t cVal){
2
  uint8_t u8Result;
3
  uint8_t * u8Data = (uint8_t *) &oSPI->DR;
4
5
  *u8Data = cVal;
6
  while(!(oSPI->SR & SPI_SR_RXNE));
7
  u8Result = oSPI->DR;
8
9
  return u8Result;
10
}

von Albert (Gast)


Lesenswert?

Ebenso hat eine Änderung der Datenbreite auf z.B. 4Bit auch keine 
Auswirkung, es werden immernoch die gleiche Anzahl an Takten gesendet.

oSPI->CR2 |= (0b0011ul << 8); //4Bit

von Albert (Gast)


Lesenswert?

Hier mein aktueller Code, der nach wie vor 2 bytes schickt. Das mit dem 
"Data Packing" habe ich soweit verstanden, aber es werden trotzdem zwei 
Bytes verschickt:
1
void SPI_Init(SPI_TypeDef * oSPI, uint8_t ucPrescaler){
2
  oSPI->CR1 = 0;
3
  oSPI->CR2 = 0;
4
  oSPI->CR1 |= SPI_CR1_SSM;
5
  //oSPI->CR1 |= SPI_CR1_SSI;
6
  //oSPI->CR1 |= SPI_CR1_LSBFIRST;
7
  //oSPI->CR1 |= SPI_CR1_CPHA;
8
  //oSPI->CR1 |= SPI_CR1_CPOL;
9
  oSPI->CR1 |= SPI_CR1_MSTR;
10
  oSPI->CR1 |= ((uint16_t)ucPrescaler<<3);
11
  oSPI->CR2 |= (0b0111ul << 8);
12
  oSPI->CR2 |= SPI_CR2_SSOE;
13
  oSPI->CR2 |= SPI_CR2_FRXTH;
14
  //oSPI->CR2 |= SPI_CR2_FRF;
15
  oSPI->CR1 |= SPI_CR1_SPE;
16
}
17
18
uint8_t SPI_Send(SPI_TypeDef * oSPI, uint8_t cVal){
19
  uint8_t u8Result;
20
21
  *(uint8_t *)&oSPI->DR = cVal;
22
  while(!(oSPI->SR & SPI_SR_RXNE));
23
  //u8Result = oSPI->DR;
24
25
  return u8Result;
26
}

von foobar (Gast)


Lesenswert?

I2SMOD ist aus?

von Albert (Gast)


Lesenswert?

foobar schrieb:
> I2SMOD ist aus?

Gibts bei meinem STM32 nicht. Aber ich habe die Ursache gefunden, mein 
Cast wurde wegoptimiert und ich musste ein volatile einfügen:
1
*(volatile uint8_t *)&oSPI->DR = cVal;

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.