Impossible de recevoir la trame CAN sur STM32 en raison d’une collision inattendue

lesenk

Impossible de recevoir la trame CAN sur STM32 en raison d’une collision inattendue


J’essaie de recevoir des trames CAN sur un STM32F412G-DISCOVERY avec un émetteur-récepteur SN65HVD233, transmis à partir d’un périphérique USB2CAN. Les deux sont connectés sur un bus d’environ 15 cm de long avec deux résistances de 120 Ω à chaque extrémité.

J’ai connecté un oscilloscope pour lire les broches RX et TX sur la carte STM32 avant qu’elles ne soient transformées par l’émetteur-récepteur. Lorsque je configure le contrôleur CAN en mode silencieux et envoie une trame CAN depuis l’USB2CAN en utilisant:

$ cansend can0 '144#25'

Je vois sur l’oscilloscope sur la broche RX le cadre complet (le jaune est le RX de la carte, le bleu son TX):

NB: le curseur indique l’intervalle de temps d’un bit (2 µs, le débit est de 500 kb / s).

(L’ HAL_CAN_Receiveappel s’arrête toujours, mais c’est un autre problème.) Mais quand je mets le contrôleur en mode normal, voici ce que je mesure:

entrez la description de l'image ici

Et voici le code:

hcan1.pTxMsg = &g_out_msg;
hcan1.pRxMsg = &g_in_msg;
hcan1.Instance = CAN1;
hcan1.Init.Prescaler = 12;
hcan1.Init.Mode = CAN_MODE_NORMAL;
hcan1.Init.SJW = CAN_SJW_1TQ;
hcan1.Init.BS1 = CAN_BS1_1TQ;
hcan1.Init.BS2 = CAN_BS2_1TQ;
hcan1.Init.TTCM = DISABLE;
hcan1.Init.ABOM = DISABLE;
hcan1.Init.AWUM = DISABLE;
hcan1.Init.NART = DISABLE;
hcan1.Init.RFLM = DISABLE;
hcan1.Init.TXFP = DISABLE;

if (HAL_CAN_Init(&hcan1) != HAL_OK)
    fatal_error("failed to init HAL CAN.");

CAN_FilterConfTypeDef sFilterConfig;
sFilterConfig.FilterNumber         = 0;
sFilterConfig.FilterMode           = CAN_FILTERMODE_IDMASK;
sFilterConfig.FilterScale          = CAN_FILTERSCALE_32BIT;
sFilterConfig.FilterIdHigh         = 0x0000;
sFilterConfig.FilterIdLow          = 0x0000;
sFilterConfig.FilterMaskIdHigh     = 0x0000;
sFilterConfig.FilterMaskIdLow      = 0x0000;
sFilterConfig.FilterFIFOAssignment = 0;
sFilterConfig.FilterActivation     = ENABLE;
sFilterConfig.BankNumber           = 14;
if (HAL_CAN_ConfigFilter(&hcan1, &sFilterConfig) != HAL_OK)
    fatal_error("failed to setup CAN filter.");

HAL_StatusTypeDef can_status;
if ((can_status = HAL_CAN_Receive(&hcan1, CAN_FIFO0, 20000)) != HAL_OK)
    fatal_error("failed to receive frame: %d", can_status);

Il semble que l’émetteur (USB2CAN) ait tenté d’écrire un récessif (1) pour le 2ème bit de l’ID tandis que le récepteur (STM32) envoyait un dominant (0): l’émetteur a détecté cette collision et a cessé d’émettre.

Pourquoi le contrôleur CAN STM32 a-t-il envoyé ce bit dominant qui a interrompu la communication?

Réponses


 Jeroen3

Un décalage temporel.

Le STM32 émet un indicateur d’erreur. Sinon, pourquoi transmettrait-il quoi que ce soit directement après les premiers bits?

Le cadre d’erreur est censé être long de 6 bits, mais dans votre image, la largeur des curseurs ne tient pas dans le cadre tx 6 fois. Cela signifie que les contrôleurs n’utilisent pas le même débit binaire.

lesenk

Le STM32 est configuré avec un prescaler de 12 qui correspond à un « temps pour un bit » de 2000 ns selon CubeMX, n’est-ce pas un débit de 500 kb / s?

lesenk

Apparemment, le STM32 a utilisé un débit réel de 250 kb / s (?!), En doublant le débit, j’obtiens maintenant ceci: i.imgur.com/FJ0wge9.jpg ; Je ne comprends toujours pas pourquoi le STM32 dit quoi que ce soit à côté de l’acking du cadre.

lesenk

C’était effectivement un problème de timing. J’ai utilisé un prescaler de 4 avec 7/1 pour BS1 / BS2 et ça marche maintenant!

 

#de, #en, #la, CAN, collision, d’une, impossible, inattendue, raison, recevoir, STM32?, sur, trame

 

google

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *