Forum: Mikrocontroller und Digitale Elektronik SPI Code STM32F103


von Alfa (Gast)


Lesenswert?

Hallo zusammen,

Ich versuche nun schon den ganzen Tag nach unzähligen erfolglosen 
Versuchen eine SPI Kommunikation zu einem ADT7320 Temperatursensor 
aufzubauen. Leider erfolglos.


Hat eventuell jemand einen beispielcode für einfache SPI Kommunikation 
ohne DMA und Interrupts?

Ich will einfach nur das ID REGISTER des Chips auslesen.

Bin für jedes funktionierende Beispiel auf dem o.g. Controller dankbar!

von Baldrian (Gast)


Lesenswert?

Gibt's doch in den ST Libs oder in libopencm3.

von Mojo (Gast)


Lesenswert?

Gemeine Falle ist wenn du als Master nicht den NSS setzt.

SPI_InitTypeDef spiInit;
SPI_StructInit(&spiInit);
...
spiInit.SPI_NSS = SPI_NSS_Soft;
SPI_NSSInternalSoftwareConfig( SPI1, SPI_NSSInternalSoft_Set );

von Alfa (Gast)


Lesenswert?

Mojo: Ich habe das "SPI_NSSInternalSoftwareConfig( SPI1, 
SPI_NSSInternalSoft_Set );" noch ergänzt. Leider erfolglos.
Ich versuche einen ADT7320 Temperatursensor anzusteuern. Die Ansteuerung 
funktioniert auf einem ATmega2560 bereits erfolgreich. Das Programm 
läuft mit CoOs, jedoch habe ich den selben Code auch schon ohne CoOs mit 
dem selben Ergebnis getestet. Orientiert habe ich mich (unter anderem) 
auch an diesem Thread: Beitrag "SPI Probleme zwischen STM32 und ADT7310"

Eventuell hat jemand eine Idee woran es liegen könnte? Hier noch die 
Ausgabe des Programms:

CoOS RTOS: Creating tasks
CoOS RTOS: Starting scheduler
CoOS 'taskA' started
CoOS 'taskB' started
CS1 SET
CS1 RESET
ADT7320 RESET OK
CS1 SET
VOR RR8 SPI WRITE: OK


Danach hängt er sich auf. Ich verzweifele hier langsam.

Hier mal mein Code:
1
/********** Init SPI **********/
2
3
InitSPI1(){
4
5
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO | RCC_APB2Periph_SPI1, ENABLE);
6
7
  GPIO_InitStructure.GPIO_Pin = MB_SPI1SCK_PIN | MB_SPI1MISO_PIN;
8
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
9
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
10
  GPIO_Init(GPIOA, &GPIO_InitStructure);
11
12
  GPIO_InitStructure.GPIO_Pin = MB_SPI1MOSI_PIN;
13
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
14
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
15
  GPIO_Init(GPIOA, &GPIO_InitStructure);
16
17
  GPIO_InitStructure.GPIO_Pin = MB_CS_CJ1_Pin;
18
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
19
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
20
  GPIO_Init(GPIOA, &GPIO_InitStructure);
21
22
  GPIO_WriteBit(GPIOA, MB_CS_CJ1_Pin, SET);
23
24
  SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_32;
25
  SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
26
  SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;
27
  SPI_InitStructure.SPI_CRCPolynomial = 0;
28
  SPI_InitStructure.SPI_DataSize = SPI_DataSize_16b;
29
  SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
30
  SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
31
  SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
32
  SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
33
  SPI_NSSInternalSoftwareConfig( SPI1, SPI_NSSInternalSoft_Set );
34
35
  SPI_Init(SPI1, &SPI_InitStructure);
36
37
  SPI_Cmd(SPI1, ENABLE);
38
}
39
40
41
/********** CoOS Task **********/
42
43
void taskB (void* pdata)
44
{
45
46
  if (DebugLevel == 2) {
47
      USART_PutString(USART1,"CoOS 'taskB' started\n");
48
    }
49
50
  ADT7320_Reset(1);
51
  Delay(0xFF);
52
  while(1){
53
54
    GPIOA->BSRR = MB_LedYellow_Pin;
55
    
56
    uint16_t regdataID = 0;
57
    uint16_t regdataSTATUS = 0;
58
    char s_regdataID[10] = "";
59
    
60
    regdataID = ADT7320_ReadRegister8(1, ADT7320_REG_ID);
61
    regdataSTATUS = ADT7320_ReadRegister8(1,ADT7320_REG_STAT);
62
    
63
    sprintf(s_regdataID, "%d", regdataID);
64
    USART_PutString(USART1,s_regdataID);
65
    USART_PutString(USART1,"\n");
66
    
67
    CoTickDelay (100);
68
    GPIOA->BRR = MB_LedYellow_Pin;
69
    CoTickDelay (100);
70
  }
71
}
72
73
74
/********** ADT7320 Reset **********/
75
76
void ADT7320_Reset(uint8_t cs)
77
{
78
  uint16_t data = 0;
79
  ADT7320_Select(cs);      // Select (Active Low)
80
  data = SPI_Write(0xFFFF);
81
  data = SPI_Write(0xFFFF);
82
  ADT7320_Deselect(cs);    // Deselect (Active Low)
83
  Delay(0xFF);
84
  USART_PutString(USART1,"ADT7320 RESET OK\n");
85
}
86
87
/********** ADT7320 ReadRegister 8 **********/
88
89
uint16_t ADT7320_ReadRegister8(uint8_t cs, uint8_t reg)
90
{
91
  uint16_t data = 0;
92
  // reg = 3, da IDREG
93
  reg = reg << 3;
94
  ADT7320_Select(cs);
95
  USART_PutString(USART1,"VOR RR8 SPI WRITE: OK\n");
96
  uint16_t regdata16 = (uint16_t)(0x40 | reg);
97
  data = SPI_Write(regdata16);    // write to comm reg
98
  USART_PutString(USART1,"RR8 SPI WRITE: OK\n");
99
  Delay(0xFF);
100
  ADT7320_Deselect(cs);
101
  Delay(0xFF);
102
103
  return data;
104
}
105
106
107
/********** SPI Write **********/
108
109
uint16_t SPI_Write(uint16_t data) {
110
  while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET); //wait buffer empty
111
  SPI_I2S_SendData(SPI1, data);
112
  while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == SET); //wait finish sending}
113
  Delay(0x0F);
114
  return (uint16_t)SPI_I2S_ReceiveData(SPI1);
115
}
116
117
118
/********** Select / Deselect **********/
119
120
void ADT7320_Select(uint8_t cs){
121
122
  if (cs == 1){
123
    MB_CS_CJ1_Port->BSRR = MB_CS_CJ1_Pin;
124
    USART_PutString(USART1,"CS1 SET\n");
125
  }
126
  else if (cs == 2){
127
    MB_CS_CJ2_Port->BSRR = MB_CS_CJ2_Pin;
128
  }
129
  else if (cs == 3){
130
    MB_CS_CJ3_Port->BSRR = MB_CS_CJ3_Pin;
131
  }
132
  else{
133
    //
134
  }
135
}
136
137
void ADT7320_Deselect(uint8_t cs){
138
139
  if (cs == 1){
140
    MB_CS_CJ1_Port->BRR = MB_CS_CJ1_Pin;
141
    USART_PutString(USART1,"CS1 RESET\n");
142
  }
143
  else if (cs == 2){
144
    MB_CS_CJ2_Port->BRR = MB_CS_CJ2_Pin;
145
  }
146
  else if (cs == 3){
147
    MB_CS_CJ3_Port->BRR = MB_CS_CJ3_Pin;
148
  }
149
  else{
150
    //
151
  }
152
}

von Alfa (Gast)


Lesenswert?

Hat keiner einen Vergleichscode? Ich probiere schon wieder den ganzen 
Tag und kann keinen wirklichen Unterschied zu den anderen Beispiel 
feststellen.

Hab ich etwas auf den Augen?
Vielleicht seh ich es einfach nicht mehr...

von Alfa (Gast)


Lesenswert?

Niemand eine Idee?
Hie sind doch eine ganze Menge STM Experten.

von Menge (Gast)


Lesenswert?

Es lohnt sich definitiv, für ein paar Euro einen "Logic Analyser"
oder für ein paar Euro mehr einen Logic Analyser anzuschaffen.
Notfalls ist auch ein STM32F4Disco als solcher verwendbar.

Spart viel Zeit...

von Mehmet K. (mkmk)


Lesenswert?

Alfa schrieb:
> Niemand eine Idee?
> Hie sind doch eine ganze Menge STM Experten.
Na ja, wenn sich jemand als Alfa titulierend auf der Bühne plaziert, ist 
für den Rest des Rudels halt die Hemmschwelle etwas gross, sich zu Wort 
zu melden.

Ich habe nicht das Ganze mir angesehen; aber gleich am Anfang stolperte 
ich über folgende Zeilen:
1
GPIO_InitStructure.GPIO_Pin = MB_SPI1SCK_PIN | MB_SPI1MISO_PIN;
2
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
3
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
4
GPIO_Init(GPIOA, &GPIO_InitStructure);
5
6
GPIO_InitStructure.GPIO_Pin = MB_SPI1MOSI_PIN;
7
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
8
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
9
GPIO_Init(GPIOA, &GPIO_InitStructure);

MOSI = Microcontroller OUT, Slave IN
Da macht es nicht sehr viel Sinn, dies als GPIO_Mode_IN_FLOATING zu 
definieren.

von Menge (Gast)


Lesenswert?

PS:
Das:

>  GPIO_WriteBit(GPIOA, MB_CS_CJ1_Pin, SET);

im Vergleich zu

>     MB_CS_CJ1_Port->BSRR = MB_CS_CJ1_Pin;

ist mindestens inkonsequent. Dann wären Deine
eher verschleiernden "ADT7320_Select" und "ADT7320_Deselect"
unnötig. 30 Zeilen Code gespart, Wartungssicherheit und Lesbarkeit 
verbessert.
Hättest Du in den Stunden der Verzweiflung auch 'mal aufräumen
können.


Wieso lässt Du Dir die Werte, die der ADT7320 liefert, nicht
ausgeben (z.b. in "ADT7320_ReadRegister8")?

von dummy (Gast)


Lesenswert?

Wo rufst du das auf?

InitSPI1()

von chris (Gast)


Angehängte Dateien:

Lesenswert?

Kannst dich ja mal durch meinen Code wühlen.
Alle Funktionen hab ich nicht getestet, aber die Basisfunktionen müssten 
gehen.

von chris (Gast)


Lesenswert?

Nachtrag:
Der Code ist für einen STM32F100VB geschrieben (STM32VL Discovery).

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.