Forum: Mikrocontroller und Digitale Elektronik STM32: Problem mit SPI und Chip Select


von dulli (Gast)


Lesenswert?

Hallo zusammen,

ich programmiere mit dem STM32F0 und der HAL-Lib und habe ein Problem.

Ich will per SPI 24 Bit senden, allerdings kann ich bei 
hspi1.Init.DataSize maximal 16 Bits auswählen für ein zu sendendes 
Paket.
Also habe ich 8 Bits ausgewählt und will nun einfach 3 Pakete 
hintereinander senden. Das Problem ist nun, dass mein Chip Select nach 
jedem Paket (nach jeden 8 Bits) wieder High wird und dadurch die 
Kommunikation abgebrochen wird.

Hier meine Funktionen:
1
void senden(uint8_t data1, uint8_t data2, uint8_t data3){
2
  
3
  uint8_t *pointer;
4
  uint8_t data;
5
  
6
  pointer= &data;
7
  
8
  HAL_GPIO_WritePin(GPIOA,GPIO_PIN_4, GPIO_PIN_RESET);  //CS Low
9
  
10
  data=data1;
11
  HAL_SPI_Transmit(&hspi1, pointer, 1, 10);  //Device Opcode
12
  
13
  data=data2;
14
  HAL_SPI_Transmit(&hspi1, pointer, 1, 10);  //Register Adress
15
  
16
  data=data3;
17
  HAL_SPI_Transmit(&hspi1, pointer, 1, 10);  //Data
18
    
19
  HAL_GPIO_WritePin(GPIOA,GPIO_PIN_4, GPIO_PIN_SET);  //CS HIGH  
20
}
21
22
23
static void MX_SPI1_Init(void)
24
{
25
26
  hspi1.Instance = SPI1;
27
  hspi1.Init.Mode = SPI_MODE_MASTER;
28
  hspi1.Init.Direction = SPI_DIRECTION_1LINE;
29
  hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
30
  hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;
31
  hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
32
  hspi1.Init.NSS = SPI_NSS_SOFT;
33
  hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_64;
34
  hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
35
  hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
36
  hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
37
  hspi1.Init.CRCPolynomial = 7;
38
  hspi1.Init.CRCLength = SPI_CRC_LENGTH_DATASIZE;
39
  hspi1.Init.NSSPMode = SPI_NSS_PULSE_ENABLE;
40
  if (HAL_SPI_Init(&hspi1) != HAL_OK)
41
  {
42
    Error_Handler();
43
  }
44
}
45
46
void HAL_SPI_MspInit(SPI_HandleTypeDef* hspi)
47
{
48
49
  GPIO_InitTypeDef GPIO_InitStruct;
50
  if(hspi->Instance==SPI1)
51
  {
52
 
53
    /* Peripheral clock enable */
54
    __HAL_RCC_SPI1_CLK_ENABLE();
55
  
56
    /**SPI1 GPIO Configuration    
57
    PA4     ------> SPI1_NSS
58
    PA5     ------> SPI1_SCK
59
    PA6     ------> SPI1_MISO
60
    PA7     ------> SPI1_MOSI 
61
    */
62
    GPIO_InitStruct.Pin = GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7;
63
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
64
    GPIO_InitStruct.Pull = GPIO_NOPULL;
65
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
66
    GPIO_InitStruct.Alternate = GPIO_AF0_SPI1;
67
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
68
69
  }
70
}

Ich habe Chip Select extra als SPI_NSS_SOFT eingestellt, dass ich ihn 
manuell auf high/low setzen kann. Aber genau das funktioniert eben 
nicht. Er geht automatisch vor jedem zu sendenden Byte auf Low und nach 
jedem Byte auf High.

von Nico W. (nico_w)


Lesenswert?

dulli schrieb:
> Er geht automatisch vor jedem zu sendenden Byte auf Low und nach
> jedem Byte auf High.

Na, dann kennst du doch schon dein Problem.

Guck dir doch mal die Funktion an, die das macht (HAL_SPI_Transmit). 
Vielleicht hat der SPI_HandleTypeDef ja noch ne Option dafür über?

Ich kenne allerdings die HAL nicht. Aber der Quellcode liegt ja 
anscheinend bei dir vor.

von Gerald (Gast)


Lesenswert?

dulli schrieb:
> Aber genau das funktioniert eben
> nicht. Er geht automatisch vor jedem zu sendenden Byte auf Low und nach
> jedem Byte auf High.
Wie hast Du das festgestellt? Mit dem Oszilloskop?

von dulli (Gast)


Lesenswert?

Gerald schrieb:
> Wie hast Du das festgestellt? Mit dem Oszilloskop?

Genau habe CS, SCK und MISO mit dem Oszi gemessen und dabei ist es mir 
aufgefallen.

von Gerald (Gast)


Lesenswert?

dulli schrieb:
> /**SPI1 GPIO Configuration
>     PA4     ------> SPI1_NSS
>     PA5     ------> SPI1_SCK
>     PA6     ------> SPI1_MISO
>     PA7     ------> SPI1_MOSI
>     */
Ich glaube Du musst den /CS Pin dann entsprechend als GPIO definieren:
1
    GPIO_InitStruct.Pin = GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7;
2
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
3
    GPIO_InitStruct.Pull = GPIO_NOPULL;
4
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
5
    GPIO_InitStruct.Alternate = GPIO_AF0_SPI1;
6
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
7
8
    GPIO_InitStruct.Pin = GPIO_PIN_4;
9
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
10
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

von dulli (Gast)


Lesenswert?

üüüü

Gerald schrieb:
> Ich glaube Du musst den /CS Pin dann entsprechend als GPIO definieren:

Das hat geholfen. Danke!

von Joe F. (easylife)


Lesenswert?

Wenn ich diesen Thread hier richtig verstehe, ist das 3. Argument an 
HAL_SPI_Transmit() die Anzahl der Bytes, die übertragen werden sollen.

Beitrag "STM32 HAL_SPI_Transmit, wofür Size?"

data muss dann natürlich ein byte-Array sein.
also vermutlich so:
1
  uint8_t data[3];
2
  data[0]=data1;
3
  data[1]=data2;
4
  data[2]=data3;
5
  
6
  HAL_GPIO_WritePin(GPIOA,GPIO_PIN_4, GPIO_PIN_RESET);  //CS Low
7
  
8
  HAL_SPI_Transmit(&hspi1, data, 3, 10);  //Device Opcode

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.