STM32 SPI 2 Byte senden

OP #6164226
Lesenswert?

Hallo Leute,

ich probiere mich gerade daran mit meinem STM32F411RE eine Verbindung zu 
einem MCP4922 aufzubauen. Dafür habe ich zum ersten mal eine SPI 
Schnittstelle mit hilfe der HAL Lib erstellt. Ich scheitere aber daran 2 
bytes hintereinander zu senden.
1
char message[] = "H";
2

3
HAL_GPIO_WritePin(GPIOA, SPI1_CS_Pin, 0);
4

5
HAL_SPI_Transmit(&hspi1,(uint8_t *)message, strleng(message), HAL_MAX_DELAY);
6

7
HAL_GPIO_WritePin(GPIOA, SPI1_CS_Pin, 1);
Dieser code funktioniert. Es wird genau 1 Byte gesendet mit dem inhalt 
"H".
Soweit ganz gut, als nächstes wollte ich nun meine eigenen 2 Byte mit 
dem Inhalt versenden, der dem Register des MCP4922 entspricht.
1
char low_byte, high_byte;
2

3
high_byte |= (0x01 << 4);  /** ( 0 0 0 1 | ...4 data bits ) [A/B = 0 -> write to DAC A ; BUF = 0 -> unbuffered; GA = 0 -> 2x; SHDN = 1 active mode operation]*/
4
low_byte  |= ((0x01 << 7)|(0x01 << 6)|(0x01 << 5)|(0x01 << 4)|(0x01 << 0));    /** ( 1 1 1 1 | 0 0 0 1)*/
5

6
HAL_GPIO_WritePin(GPIOA, SPI1_CS_Pin, 0);
7

8
HAL_SPI_Transmit(&hspi1,(uint8_t *)high_byte, strleng(message), HAL_MAX_DELAY);
9

10

11
HAL_SPI_Transmit(&hspi1,(uint8_t *)low_byte, strleng(message), HAL_MAX_DELAY);
12

13

14
HAL_GPIO_WritePin(GPIOA, SPI1_CS_Pin, 1);

Das Ergebnis stimmt leider vorne und hinten nicht... Was mache ich bei 
der Übertragung falsch?
Gast #6164240
Lesenswert?

Walt N. schrieb:
> Das Ergebnis stimmt leider vorne und hinten nicht..

> (uint8_t *)high_byte
Warum du ein "Byte" zum Zeiger castest ist mir ein Rätsel.
Und was der Zeiger dann mit strleng(message) zu tun hat, verstehe ich 
auch nicht.

Wie auch immer, mich wundern unerwünschte Ergebnisse nicht.
Gast #6164700
Lesenswert?

Man kann es sich auch schwer machen....
Im Übrigen sieht man relativ leicht was eine Funktion haben will, wenn 
man sich die Übergabeparameter anschaut und die Beschreibung liest.
1
uint8_t data[2];
2

3
data[0] |= (0x01 << 4); 
4
data[1]  |= ((0x01 << 7)|(0x01 << 6)|(0x01 << 5)|(0x01 << 4)|(0x01 << 0));    
5

6
HAL_GPIO_WritePin(GPIOA, SPI1_CS_Pin, 0);
7
HAL_SPI_Transmit(&hspi1, data, 2, HAL_MAX_DELAY);
8
HAL_GPIO_WritePin(GPIOA, SPI1_CS_Pin, 1);

PS: die meisten SPI von den STMs kann man so konfigurieren das sie 
gleich 16 Bit schicken. Dann müsste entsprechend eine 1 statt einer 2 
bei der Länge stehen.
OP #6164968
Lesenswert?

Zusätzlich stellt sich jetzt noch eine weitere Frage. Ich würde mit dem 
MCP4922 gerne einen Sinus mit 40 KHz generieren. Die Auflösung ergibt 
sich, wie viele Werte für eine ganze Schwingung innerhalb von 0,025 ms 
mit dem MCP4922 ausgeben kann. Im Bild Anhang sind 3 Ouputs meiner SPI 
Schnittstelle zu sehen. Ab einem Baudratenprescaler 16 sieht das clk 
Signal nicht nach einer klassischen clock aus. Die Bitfolge scheint 
dennoch zu stimmen wenn man es vergleicht. Liegt das vielleicht an 
meinem china logic analyzer ? Der MCP wird mit dieser clock die Bitfolge 
wohl nicht entschlüsseln können, oder? (Bauteil kommt morgen und ich 
bereite die SPI Schnittstelle vor)
Angehängte Dateien:
OP #6166535
Lesenswert?

John Doe schrieb:
> Welche Samplerate hast Du eingestellt?

Dem bin ich heute nachgegangen. Meine SPI1 Schnittstelle hängt am APB2 
Bus, laut CubeMX habe ich dort eine clock von 16 MHz. In der 
SystemClock_config() function habe ich einen teiler durch 1.
1
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
In meiner SPI1 init function habe ich einen Baudrateprescaler 2 also den 
kleinsten eingestellt.
1
  hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2;
Das bedeutet dass ich mein clock Signal an der SPI1 Schnittstelle 8MHz 
beträgt. 125 nS beträgt die Periodendauer von 8MHz. Will ich nun einen 
Wert an den mcp4922 senden bedeutet das 16 * 125 nS = 2µs pro Wert. Für 
einen sinus brauch ich leider mehr Werte als einen. Gehen wir mal von 10 
Werten aus (5 pro halbwelle, keine schöner sinus aber sinusförmig). 
(16*10)*125nS = 20000ns = 20µS entsprechen 50KHz, hier ist die Zeit 
nicht einberechnet die mich der Chipselect kostet etc.
Moderator (Firma: Titel) Persönliche Seite #6166544
Lesenswert?

Walt N. schrieb:
> Das bedeutet dass ich mein clock Signal an der SPI1 Schnittstelle 8MHz
> beträgt. 125 nS beträgt die Periodendauer von 8MHz. Will ich nun einen
> Wert an den mcp4922 senden bedeutet das 16 * 125 nS = 2ms pro Wert.
Da hast du aber glatt 3 Zehnerpotenzen verschlampert.

> clock Signal an der SPI1 Schnittstelle 8MHz ... 16 Bit
Ich rechne da überschlägig, dass das Problem woanders liegt:
8MHz / 16 = 500kHz

EDIT: dürfte also bei zügiger Ansteuerung und anschließeder Filterung 
gerade so reichen. Und schneller kann der DAC mit 4,5µs Settling Time 
sowieso nicht.
OP #6166554
Lesenswert?

Lothar M. schrieb:
> Da hast du aber glatt 3 Zehnerpotenzen verschlampert.

Ist mir auch aufgefallen, verdammt.

16 * 125 nS = 2µS dauert demnach 1 Wert. 25µS entsprechen 40KHz das 
bedeutet ich bekomme höchstens 25µS/2µS = 12,5 Werte übertragen. Und da 
ist die Zeit noch nicht einberechnet die mich die Chipselect operation 
kostet. Kriege ich mit diesem setup überhaupt 40KHz hin?

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