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!
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 );
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 | }
|
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...
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...
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.
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")?
Kannst dich ja mal durch meinen Code wühlen. Alle Funktionen hab ich nicht getestet, aber die Basisfunktionen müssten gehen.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.