Ich versuche, CAN-Frames auf einem STM32F412G-DISCOVERY mit einem SN65HVD233-Transceiver zu empfangen, die von einem USB2CAN-Gerät gesendet werden. Beide sind an einem etwa 15 cm langen Bus mit zwei 120-Ω-Widerständen an jedem Ende angeschlossen.
Ich habe ein Oszilloskop angeschlossen, um die RX- und TX-Pins auf der STM32-Platine zu lesen, bevor sie vom Transceiver transformiert werden. Wenn ich den CAN-Controller im Silent-Modus konfiguriere und einen CAN-Frame vom USB2CAN sende, verwende ich:
$ cansend can0 '144#25'
Ich sehe auf dem Oszilloskop am RX-Pin das Vollbild (gelb ist der RX der Platine, blau sein TX):
Hinweis: Der Cursor zeigt das Zeitintervall von einem Bit an (2 µs, Bitrate ist 500 kb/s).
(Der HAL_CAN_Receive
Anruf läuft immer noch ab, aber das ist ein anderes Problem.) Aber wenn ich den Controller in den normalen Modus versetze, messe ich Folgendes:
Und hier ist der 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);
Es scheint, dass der Emitter (USB2CAN) versucht hat, eine rezessive (1) für das 2. Bit der ID zu schreiben, während der Empfänger (STM32) eine dominante (0) gesendet hat: Der Emitter hat diese Kollision erkannt und die Emission gestoppt.
Warum hat der STM32-CAN-Controller dieses dominante Bit gesendet, das die Kommunikation gestoppt hat?
Ein Timing-Missverhältnis.
Der STM32 gibt ein Fehlerflag aus. Warum sonst sollte es etwas direkt nach den ersten paar Bits übertragen?
Der Fehlerrahmen soll 6 Bit lang sein, aber in Ihrem Bild passt die Breite der Cursor nicht 6 Mal in den TX-Rahmen. Das bedeutet, dass die Controller nicht dieselbe Bitrate verwenden.
lesen
lesen
lesen