Suche nach FDCAN-Fehler, der nicht ist

Immer mit CAN zu arbeiten war einfach, aber etwas ist schief gelaufen (im Gerät auf dem KDPV) ...

Bild

In letzter Zeit schaffe ich es oft, den Mikrocontroller STM32H750VB zu verwenden, und in einem Gerät musste ich den CAN-Bus verwenden, aber der erste Versuch, den ich unternahm, zeigte, dass mein ganzes Selbstvertrauen ein seltsames Ergebnis ergab. Die Geschichte wird unten beschrieben.

Also zuerst über Schaltkreise. Bei KDPV ist es natürlich grün eingekreist, der Täter ist der Mikrocontroller, bei CAN gibt es nichts Kompliziertes - es wird entsprechend angeschlossen

Bild

Der MAX3051 wird als physikalische Schicht verwendet (nun, ich mag es ..), wie folgt:

Bild

Früher befand sich der STM32F107 anstelle des STM32H750VB im selben System, aber der alte Mann konnte die Aufgaben nicht bewältigen, und es wurde beschlossen, ihn durch einen moderneren und jugendlicheren zu ersetzen.

Aber hier ist das Pech - der alte Mikrocontroller hatte bxCAN und der neue hatte bereits FDCAN. Es gibt zwar Unterschiede, aber aus Sicht des Codes (und der Arbeit - die Geräte am Bus sind alt): Austausch ist sehr einfach. Für diejenigen, die wünschen, können Sie vergleichen:
WarIst geworden
  MX_CAN1_Init (); 
  MX_FDCAN1_Init (); 
     hcan1.Instance = CAN1;
     hcan1.Init.Prescaler = 4;
     hcan1.Init.Mode = CAN_MODE_NORMAL;
     hcan1.Init.SyncJumpWidth = CAN_SJW_4TQ;
     hcan1.Init.TimeSeg1 = CAN_BS1_15TQ;
     hcan1.Init.TimeSeg2 = CAN_BS2_2TQ;
     hcan1.Init.TimeTriggeredMode = DISABLE;
     hcan1.Init.AutoBusOff = ENABLE;
     hcan1.Init.AutoWakeUp = DISABLE;
     hcan1.Init.AutoRetransmission = DISABLE;
     hcan1.Init.ReceiveFifoLocked = DISABLE;
     hcan1.Init.TransmitFifoPriority = DISABLE; 
   hfdcan1.Instance = FDCAN1;
   hfdcan1.Init.FrameFormat = FDCAN_FRAME_FD_NO_BRS;
   hfdcan1.Init.Mode = FDCAN_MODE_NORMAL;
   hfdcan1.Init.AutoRetransmission = ENABLE;
   hfdcan1.Init.TransmitPause = DISABLE;
   hfdcan1.Init.ProtocolException = ENABLE;
   hfdcan1.Init.NominalPrescaler = 1;
   hfdcan1.Init.NominalSyncJumpWidth = 3;
   hfdcan1.Init.NominalTimeSeg1 = 11;
   hfdcan1.Init.NominalTimeSeg2 = 4;
   hfdcan1.Init.DataPrescaler = 1;
   hfdcan1.Init.DataSyncJumpWidth = 3;
   hfdcan1.Init.DataTimeSeg1 = 11;
   hfdcan1.Init.DataTimeSeg2 = 4;
   hfdcan1.Init.MessageRAMOffset = 64;
   hfdcan1.Init.StdFiltersNbr = 0;
   hfdcan1.Init.ExtFiltersNbr = 0;
   hfdcan1.Init.RxFifo0ElmtsNbr = 4;
   hfdcan1.Init.RxFifo0ElmtSize = FDCAN_DATA_BYTES_8;
   hfdcan1.Init.RxFifo1ElmtsNbr = 4;
   hfdcan1.Init.RxFifo1ElmtSize = FDCAN_DATA_BYTES_8;
   hfdcan1.Init.RxBuffersNbr = 4;
   hfdcan1.Init.RxBufferSize = FDCAN_DATA_BYTES_8;
   hfdcan1.Init.TxEventsNbr = 4;
  if (HAL_CAN_Init (& hcan1)! = HAL_OK) { 
  if (HAL_FDCAN_Start (& hfdcan1)! = HAL_OK) { 

Im Allgemeinen kosmetische Unterschiede. Und es schien mir, dass es auf einmal und richtig funktionieren würde.

Es hat jedoch nicht sofort funktioniert ...

Der CAN-Controller konnte keinen dominanten Pegel einstellen und ging in einen Bus-Aus-Zustand über, und es wurden keine Daten vom Bus empfangen (trotz der Tatsache, dass ein anderes Gerät auf dem Bus Pakete zweimal pro Sekunde stabil sendete).

Nun, ich dachte, die Debugging-Leitung kam und verlötete die Verkabelung auf den CAN-RX- und CAN-TX-Leitungen (tatsächlich sah es logisch aus, den Bus selbst zu sehen - das Gerät war still und das angeschlossene andere Gerät sendete Pakete , wie vereinbart ).

Danach wurde der Modus FDCAN_MODE_BUS_MONITORING zum ersten Mal aktiviert. Und siehe da, ich habe sofort Pakete aus dem Bus gesehen! (In diesem Modus hört der CAN-Controller nur auf die Daten, sendet aber nichts). So toll ...

Als nächstes wurde der FDCAN_MODE_EXTERNAL_LOOPBACK-Modus aktiviert (in diesem Modus hören wir im Gegenteil nur uns selbst zu, übertragen dann aber alles auf den Bus). Und auf den Leitungen CAN_RX und CAN_TX erschienen alle Datenpakete - hier vom Gerät selbst gesendet und vom Bus empfangen
In der folgenden Abbildung (graue Daten TX vom Mikrocontroller, orange Datenleitung RX) sind sie als Peaks sichtbar:

Bild

Nach diesem Experiment wurde klar, dass die Schaltung korrekt funktioniert und der CAN-Controller im Mikroprozessor sowohl Daten empfangen als auch senden kann.

Bei dem Versuch, Daten gleichzeitig zu empfangen und zu senden, wurde das System jedoch immer noch mit einem Fehler im Fehlerüberwachungsregister (FDCAN-Protokollstatusregister (FDCAN_PSR)) LEC [2: 0] = 5 - was aus dem Datenblatt Bit0Error: During die Übertragung einer Nachricht (oder eines Bestätigungsbits oder eines aktiven Fehlers)
flag oder overload flag), das Gerät wollte einen dominanten Pegel (Daten- oder Identifizierungsbit) senden
logischer Wert 0), aber der überwachte Buswert war rezessiv ...

Nach zwei Tagen der Qual (es ist klar, was der Fehler ist, aber es ist nicht klar, wie er behoben werden kann) und einem durchdachten Studium des Datenblattes, der Errata und einer Reihe von Code und Handbüchern von Drittanbietern wurde mir klar, dass ich alles richtig mache, aber es funktioniert nicht!

Nun, ich dachte, vielleicht liegt die Sache in der Technologie und ... ersetzte den Mikrocontroller selbst (durch einen anderen aus derselben Charge). Und ... es hat funktioniert! Nun, das heißt, hier ohne mit einem Tamburin von Problemen zu tanzen , mit dem Quellcode und wie es das erste Mal sein sollte.

Kurze Zusammenfassung


Anscheinend ist so ein listiges Exemplar aufgetaucht. Andererseits habe ich es geschafft, mich eingehender mit der Arbeit von FDCAN im Allgemeinen zu befassen, was auf die Pluspunkte zurückzuführen ist. Und den Minuspunkten ... Und ihnen ist die verlorene Zeit (der Controller könnte an ein anderes Projekt gebunden sein) und das Verständnis zuzuschreiben, dass moderne Controller auch auf moderne Weise mit schrecklicher Kraft buggy sind (oder ist das auch ein Pluspunkt?).

Source: https://habr.com/ru/post/de483590/


All Articles