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


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
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.