Hallo,
ich möchte die CAN-Schnittstelle an meinem STM32F4Discovery nutzen.
Die Hardware sollte soweit passen...
Ich habe an einem STM32F4Discovery PD0/PD1 einen MCP2662 angeschlossen.
Wenn ich ein funktionierenden Sensor an den Bus (H/L) anstecke, sehe ich
mit dem Oszi wie zyklische Daten über die CANRx-Leitung zum STM
gesendet werden.
Ebenso kann ich etwas auf der CanTx-Leitung sehen wenn ich eine
Nachricht sende.
Irgendwie klappt es aber aus meiner Sicht mit dem "lesen" nicht. Sprich,
dass die Daten in mein uint8_t Array geschrieben werden.
Ich habe in dem Programm nichts weiter als eine LED-welche mit 0,5Hz
getoggelt wird.
Das erste Ziel wäre da eine Nachricht zu senden und im LoopBack wieder
zu lesen.
Es geht jedenfalls nicht so ...
Die Funktion "HAL_CAN_GetRxMessage" hat den Rückgabewert 1.
HAL_CAN_GetError gibt "2097152"
HAL_CAN_GetRxFifoFillLevel gibt den Wert 0 zurück.
Ich merke zunehmend wie meine Suche mehr einem "stochern" ähnelt.
Die Änderungen in der HAL-Lib verwirren mich zusätzlich...
Es gibt ja schöne Beispiele im Netz wo die Rx/Tx-Header mit im
CAN-Handle untergebracht sind (hcan.pTxMsg = &TxMessage;hcan.pRxMsg =
&RxMessage;). Das gibts aber offensichtlich in der verwendeten
HAL-Version nicht mehr...
Ein bisschen hab die die Vermutung das ich mit den Pointern was falsch
mache. Könnte mir bitte jemand einen Tipp geben?
Hier der Quellcode auszugsweise:
OK.
Ich hatte irgendwo gelesen, dass dann alle Nachrichten durchkommen (bei
DISABLE).
Dann müsste ich auch die FilterIdHigh & FilterIdLow richtig
konfigurieren.
Stimmt es dann, dass alle Nachrichten passieren wenn beide auf 0x0000
stehen?
RainerZufall24 schrieb:> Ich hatte irgendwo gelesen, dass dann alle Nachrichten durchkommen (bei> DISABLE).
Normalerweise kommt gar nichts durch, und du musst Filter Banks so
einstellen und aktivieren, dass das Gewünschte durch kommt.
RainerZufall24 schrieb:> Stimmt es dann, dass alle Nachrichten passieren wenn beide auf 0x0000> stehen?
Ich meine schon. Lies das nochmal im Reference Manual durch und schau
dir den Quellcode der HAL an, um festzustellen, was du da hinschreiben
musst, damit das richtige in der Hardware ankommt. Die HAL ist an der
Stelle etwas komisch, man muss das quasi rückwärts machen. Alternativ
die HAL einfach gar nicht benutzen, dann entfällt dieser Schritt...
RainerZufall24 schrieb:> Ansich ist die HAL schon gut zu verwenden ...> Ohne die wird's vermutlich nicht viel einfacher.>> Wo finde ich den eine Erläuterung zu den HAL-Error?
Im HAL-Sourcecode. Den muss man mangels vernünftiger Doku immer parat
haben...
Hallo,
ich habe noch nie CAN mit der HAL verwendet, aber folgende Dinge fallen
mir schnell mal auf:
* Beim Senden musst Du irgendwo festlegen welcher Frametyp (Remote,
Data), welche ID (SID oder EID) und wieviele Datenbytes Du senden
möchtest.
Sehe ich in Deinem Code nirgends.
* Soweit ich Deine Schleife verstehe prüfst Du nur einmalig, vor wem
while() ob ein Frame empfangen wurde, danach nie wieder
lg
Louis
Mist. Wieder nicht genug kopiert.
Zum Hintergrund: Ich habe das letzt Mal eine kleine Rüge bekommen weil
der zitierte Code zu lang war. Daher dacht ich mir, ich kürze ein und
hänge die wichtigen Funktionen an.
Hier die fehlenden Zeilen:
1
TxHead->StdId=0x100;
2
TxHead->ExtId=0x01;
3
TxHead->RTR=CAN_RTR_DATA;
4
TxHead->IDE=CAN_ID_STD;
5
TxHead->DLC=8;
Das Abfragen innerhalb der while() hatte ich auch schon versucht...
Klappte auch nicht.
Gibt es irgendwo ein Programmbeispiel für CAN ohne die HAL?
Viele Dank für die Hilfe
RainerZufall24 schrieb:> Das sind immer nur welche mit älteren HAL-Ständen.
Ich habe gerade nur das STM32CubeF1 installiert, und da gibt es:
~/STM32Cube/Repository/STM32Cube_FW_F1_V1.7.0/Projects/STM3210E_EVAL/Exa
mples/CAN/
Beim STM32CubeF4 müsste es etwas ähnliches geben. Das sollte doch zur
gleichzeitig installierten HAL passen.
Sorry, jetzt war ich total verwirrt.
Ich wollte eigentlich "Louis (Gast)" fragen ob das eine Doku zu den
LL-CAN Funktionen gibt. In dem HAL- Dokument ist da nichts aufgeführt.
Hallo,
der PARAM-Error wird bei HAL_CAN_GetRxMessage gesetzt, wenn in
angegebenen FiFo noch nichts empfangen wurde. in HAL_CAN_AddTxMessage
wird der Fehler gesetzt, wenn keine Senden-FiFo mehr frei ist.
Ersteres kann an Deinen Filtern liegen, letzteres an einem Bus-Error
(kein Empfänger sendet Ack, der Controller ist im Bus-Off o. ä.).
Allerdings schreibst Du auch, dass Du am Anfang des Programms eine
Nachricht senden möchtest um dann in der Schleife regelmäßig eine
Nachricht zu empfangen. Erstens mach das Programm es anders herum (es
versucht erst eine zu empfangen und sendet dann regelmäßig eine) und
zweitens kannst Du nicht regelmäßig eine Botschaft "empfangen" (also aus
dem CAN-Controller herauslesen), da das Timing vom Sender bestimmt wird
und jede gesendete/empfangene Botschaft nur einmal gelesen werden kann.
Was Du machen kannst ist entweder regelmäßig nachzusehen, ob eine neue
Nachricht angekommen ist die nur dann verarbeitet wird (mit dem Risiko,
dass Deine Empfangs-FiFo vollläuft wenn Du nicht oft genug nachsiehst),
oder Du speicherst jede empfangene Nachricht in einem Interrupt in eine
feste "Mailbox" und verwendest die Daten dann regelmäßig im
Hauptprogramm (Achtung: Daten-Konsistenz der Mailbox muss dann extra
gewährleistet werden, da sonst der Empfangs-Interrupt mitten in der
Verarbeitung die Daten verfälschen kann).
Schöne Grüße,
Martin
Hallo,
ich habe genug LL Code, leider keinen den ich posten könnte..
Hast Du den CAN Mode wirklich auf CAN_MODE_LOOPBACK gesetzt
(zusatz.txt)?
In dem Fall solltest Du eigentlich alle Nachrichten die Du sendest
jedenfalls selbst empfangen können.
Tatsächlich senden / empfangen kannst Du im Loopback Mode aber nicht,
dazu brauchst Du CAN_MODE_NORMAL.
Zum Testen kann es auch hilfreich sein, bei der Initialisierung NART
("no automatic retransmit") auf true zu setzen, ansonsten kann es
schnell passieren dass Du nach dem Senden einer Nachricht in einen
Fehlerzustand kommst wenn kein Empfänger die Nachricht bestätigt.
Ansonsten wäre mein erster Tipp wenn die Kommunikation mit einem anderen
Gerät nicht klappt, nocheinmal alle Werte zum Timing durchzurechnen, man
kann da sehr schnell einen Fehler machen.
Vielleicht auch mit dem Oszilloskop die min. Bitbreite auf Plausi
überprüfen.
lg
Louis
Du solltest die HAL_CAN_GetRxMessage() in der ISR nur im Falle des
Empfangs nutzen (Callback). Sonst scheppert es immer ERRORs.
Error_Handler() implementieren (GPIO toggel, LED an, sonst was).
Mit dem Filter bestimmst du in welchen der 2 RX-FIFOs von CAN1 die
Nachricht geht.
[Für dual CAN experience: Es gibt insgesamt 4 RX-FIFOs (2 für CAN1 und 2
für CAN2). Dankenswerter Weise (Ironie) gibt es aber nur Callbacks für
FIFO0 und FIFO1. Nicht vergessen im jeweiligen Callback nachzuschauen ob
CAN1 oder CAN2 ausgelöst hat!]
Kannst du irgendwie dein Projekt *.zip machen und hochladen?
Vielen Dank nochmal für eure Hilfe.
Ich habe das Projekt nochmal neu aufgesetzt ... und nun funktioniert es.
-> siehe Anhang.
Keine Ahnung was ich falsch gemacht habe.
Weiterhin habe ich nochmal die Doku der HAL angefügt.
Die ist zwar vom STM32F1 ... passt aber soweit denke ich.
Jedenfalls habe ich mich daran gehalten (Stichwort: "How to use this
driver" -> Seite 92) und nun geht's .
Das Abarbeiten via ISR kommt als nächstest.
Nochmals vielen Dank.
RainerZufall24