Hallo, ich habe ein System mit einem bestimmten PIC-Controller, die Software auf diesem PIC ist nicht veränderbar, da sie zusammen mit anderen Systemen verwendet wird. Der PIC ist der SPI-Master und hat eine CS-, MOSI- und MISO-Verbindung zu einem STM32L471. Als erste Information: Ich bin nur ein Hobby-Programmierer, der einem alten Kollegen hilft. Also benutze ich die STM32 HAL und habe keine Zeit, den Umgang mit einer SPI mit DMA via Registerzugriffen zu lernen. Ich weiß, dass die Verwendung der Register mir die volle Kontrolle geben würde, aber das würde im Moment einfach zu viel Zeit kosten. Der STM32 ist der SPI-Slave (SPI3), der via CS getriggert wird (Active Low) und verwendet die DMA2-Kanäle 1 und 2 für SPI3_RX und SPI3_TX. Das CS liegt auf PC10 als SPI_SCK. Der NSS-Signaltyp wird in der Einstellung "Software" verwendet, da ich mit der Einstellung "Hardware NSS" nie eine korrekte Kommunikation zum laufen bekam. Der Kommunikationszyklus vom PIC beginnt alle 6 ms und dauert 3 ms. Er beginnt mit einer fallenden Flanke auf CS und endet mit einer steigenden Flanke auf CS. Ich verwende einen IRQ auf die steigenden Flanke parallel zum HAL_SPI_TxRxCpltCallback(). Die übertragenen Daten haben eine Startsequenz und eine CRC am Ende, so dass ich überprüfen kann, ob die empfangenen Daten korrekt waren oder nicht, gleiches auf der PIC-Seite. Ohne jegliche Störung funktioniert alles einwandfrei. 2017 habe ich mal ein paar Störungen getestet (SPI Kabel ausstecken/prellen etc.) und nachdem es danach auch Probleme mit geshifteten Bytes gab, dann Folgendes implementiert: Wenn die Datenprüfung in HAL_SPI_TxRxCpltCallback() einen Fehler erkannt hat, dann wird "versucht" die SPI-Kommunikation im IRQ der steigenden CS-Flanke so zurückzusetzen: HAL_SPI_Abort_IT(&hspi3); HAL_SPI_Abort(&hspi3); HAL_SPI_AbortCpltCallback(&hspi3); HAL_SPIEx_FlushRxFifo(&hspi3); HAL_SPI_DeInit(&hspi3); MX_SPI3_Init(); Wie man sieht, habe ich einfach alles was mir eingefallen ist, abgebrochen oder resettet. Aber es scheint nicht generell zu helfen. Denn diese Woche ruft mich mein Kollege mit neuen Problemen an. Manchmal scheint die SPI zu "hängen" und er hat einen Weg gefunden, die Störung Nachzustellen (Kurzschluss MOSI nach GND für kurze Zeit, dann den KS wieder entfernen). Ich habe heute versucht den Fehler einzugrenzen und festgestellt, dass nach dem Entfernen des Kurzschlusses die Funktionen oben korrekt aufgerufen werden, aber die Daten ab da im empfangenen Array um ein paar Bytes verschoben sind. Da ab hier in jedem Kommunikationszyklus die Startsequenz/CRC nicht mehr stimmt (weil verschoben), wird das am Ende jedes Kommunikationszyklusses wiederholt. Im Jahr 2017 erhielt ich den Hinweis, dass HAL_SPIEx_FlushRxFifo(&hspi3); dieses Verhalten lösen sollte. Aber es scheint nicht zu funktionieren. Ich habe keine Ahnung, wie man den SPI mit HAL-Möglichkeiten (SPI, FIFO und eventuell DMA) richtig "zurücksetzen" kann. Hat jemand das Wissen über die richtigen HAL-Funktionen oder kann mir einen Code-Ausschnitt mit einem registerbasierten Reset geben, den ich in Kombination mit der HAL-Funktionalität verwenden kann? Das wäre super. Vielen Dank Volker
Ich bin mir nicht zu 100% sicher, würde aber behaupten, dass:
1 | __HAL_SPI_RESET_HANDLE_STATE(&hspix); |
diese Aufgabe erfüllt, da jede HAL Funktion die irgend etwas mit dem SPI zu tun hat, zuerst:
1 | if(hspi->State == HAL_SPI_STATE_READY) ... |
abfragt. Es muss also eine Funktion vorher wieder Ordnung schaffen und HAL_SPI_STATE_READY setzen.
Für DMA wird es ähnlich sein:
1 | __HAL_DMA_RESET_HANDLE_STATE(&hdmax); |
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.