Rechercher une erreur FDCAN qui n'est pas

Toujours travailler avec CAN était simple, mais quelque chose s'est mal passé (dans l'appareil sur le KDPV) ...

image

Récemment, j'ai souvent réussi à utiliser le microcontrôleur STM32H750VB, et dans un appareil, j'avais besoin d'utiliser le bus CAN, mais la toute première tentative que j'ai faite a montré toute ma confiance en moi a donné un résultat étrange. L'histoire est décrite ci-dessous.

Donc, d'abord sur les circuits. Sur KDPV, il est entouré de vert, bien sûr, le coupable est le microcontrôleur, il n'y a rien de compliqué avec CAN - il est connecté selon

image

Le MAX3051 est utilisé comme couche physique (enfin, j'aime ça ..), comme ceci:

image

Auparavant, au lieu du STM32H750VB, le STM32F107 était dans le même système, mais le vieil homme ne faisait pas face aux tâches et il a été décidé de le remplacer par un plus moderne et plus jeune .

Mais voici la malchance - l'ancien microcontrôleur avait bxCAN, et le nouveau avait déjà FDCAN. Bien qu'il y ait des différences, mais du point de vue du code (et du travail - les appareils sur le bus sont vieux): le remplacement est très simple. Pour ceux qui le souhaitent, vous pouvez comparer:
ÉtaitEst devenu
  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) { 

En général, les différences cosmétiques. Et il me semblait que cela fonctionnerait à la fois et correctement.

Cependant, cela n'a pas fonctionné tout de suite ...

Le contrôleur CAN n'a pas pu définir un niveau dominant et est entré dans un état Bus-Off, et aucune donnée n'a été reçue du bus (malgré le fait qu'un autre appareil sur le bus ait envoyé des paquets de manière stable deux fois par seconde).

Eh bien, je pensais que la ligne de débogage est arrivée et a soudé le câblage des lignes CAN-RX et CAN-TX (en fait, la visualisation du bus lui-même semblait logique - l'appareil était silencieux et l'autre appareil connecté a envoyé des paquets , comme convenu ).

Après cela, le mode FDCAN_MODE_BUS_MONITORING a été activé pour la première fois. Et voilà, j'ai tout de suite vu des colis depuis le bus! (Dans ce mode, le contrôleur CAN écoute uniquement les données, mais ne transmet rien). Tellement génial ...

Ensuite, le mode FDCAN_MODE_EXTERNAL_LOOPBACK a été activé (dans ce mode, au contraire, nous ne nous écoutons que nous-mêmes, mais nous transférons tout sur le bus). Et sur les lignes CAN_RX et CAN_TX tous les paquets de données sont apparus - tous deux envoyés par l'appareil lui-même et reçus du bus, ici sur
Dans la figure ci-dessous (données grises TX du microcontrôleur, ligne de données orange RX), elles sont visibles sous forme de pics:

image

Ainsi, après cette expérience, il est devenu clair que le circuit fonctionne correctement, le contrôleur CAN du microprocesseur peut à la fois recevoir et transmettre des données.

Cependant, lors de la tentative de réception et de transmission simultanées de données, le système est devenu Bus-Off avec une erreur dans le registre de contrôle des erreurs (registre d'état du protocole FDCAN (FDCAN_PSR)) LEC [2: 0] = 5 - ce qui signifie d'après la fiche technique Bit0Error: Pendant la transmission d'un message (ou bit d'acquittement, ou erreur active
, ou drapeau de surcharge), le périphérique voulait envoyer un niveau dominant (données ou bit d'identification
valeur logique 0), mais la valeur de bus surveillée était récessive ...

Après deux jours de tourments (il est clair quelle est l'erreur, mais on ne sait pas comment y remédier) et une étude réfléchie de la fiche technique, des errata et d'un tas de codes et de manuels tiers, l' illumination est venue à ma compréhension - je fais tout bien, mais cela ne fonctionne pas!

Eh bien, j'ai pensé, peut-être que la question est dans la technologie, et ... a remplacé le microcontrôleur lui-même (par un autre du même lot). Et ... ça a marché! Eh bien, ici, sans danser avec un tambourin de problèmes, avec le code source et comme il se doit la première fois.

Bref résumé


Apparemment, un spécimen aussi rusé est tombé. Mais d'un autre côté, j'ai réussi à approfondir le travail de FDCAN en général, ce qui peut être attribué aux avantages. Et aux inconvénients ... Et à eux peut être attribué le temps perdu (le contrôleur a pu être attaché à un autre projet) et la compréhension que les contrôleurs modernes sont buggés avec une force terrible est également moderne (ou est-ce aussi un plus?).

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


All Articles