Hallo Forum,
ich suche jetzt schon 2 Tage und finde das Problem mit meiner
CAN-Übertragung nicht.
Ich habe einen STM32H573 und sende alle 500ms eine Nachricht per CAN.
Das Problem ist, dass jede 3. Nachricht doppelt gesendet wird. Und zwar
immer wenn der Tx FIFO/queue put index (TFQPI) von 2 auf 0 zurück
springt.
Mein Empfänger hat hier im Beispiel Nachricht 0x13 2 mal empfangen. Ich
habe das auch mit dem Oszi geprüft, die Nachricht kommt wirklich 2 mal
aus dem STM heraus und wird auch 2 mal von meinem Empfänger ge'ack't.
Das Verhalten tritt auch auch, wenn ich Auto-Retransmission deaktiviere.
Hier die Senderoutine
1 | if ((hfdcan->Instance->TXBRP & FDCAN_TXBRP_TRP) == 0) // no transmission pending
|
2 | {
|
3 | can_prepare_txheader(&txmsg.header, 0x123, 2, false, false);
|
4 | txmsg.data[0] = 0xAA;
|
5 | txmsg.data[1] = count++;
|
6 | HAL_FDCAN_AddMessageToTxFifoQ(hfdcan, &txmsg.header, txmsg.data);
|
7 | }
|
Im prepare_txheader passiert das hier:
1 | void can_prepare_txheader( void *pHeader, uint32_t ident, uint8_t dlc, bool bExtId, bool bRTR )
|
2 | {
|
3 | FDCAN_TxHeaderTypeDef *pHd;
|
4 | pHd = ( FDCAN_TxHeaderTypeDef* ) pHeader;
|
5 | pHd->Identifier = ident;
|
6 | pHd->IdType = bExtId ? FDCAN_EXTENDED_ID : FDCAN_STANDARD_ID;
|
7 | pHd->TxFrameType = bRTR ? FDCAN_REMOTE_FRAME : FDCAN_DATA_FRAME;
|
8 | pHd->DataLength = dlc & 0x0F;
|
9 | pHd->ErrorStateIndicator = FDCAN_ESI_ACTIVE;
|
10 | pHd->BitRateSwitch = FDCAN_BRS_OFF;
|
11 | pHd->FDFormat = FDCAN_CLASSIC_CAN;
|
12 | pHd->TxEventFifoControl = FDCAN_NO_TX_EVENTS;
|
13 | pHd->MessageMarker = 0;
|
14 | }
|
Hier noch die Init:
1 | HAL_StatusTypeDef can_fdcan_init( FDCAN_HandleTypeDef *hfdcan , uint8_t baudrateindex, bool bMonitoring )
|
2 | {
|
3 | HAL_StatusTypeDef status;
|
4 |
|
5 | hfdcan->Init.ClockDivider = FDCAN_CLOCK_DIV1;
|
6 | hfdcan->Init.FrameFormat = FDCAN_FRAME_CLASSIC;
|
7 | hfdcan->Init.Mode = bMonitoring ? FDCAN_MODE_BUS_MONITORING : FDCAN_MODE_NORMAL;
|
8 | hfdcan->Init.AutoRetransmission = ENABLE;
|
9 | hfdcan->Init.TransmitPause = ENABLE;
|
10 | hfdcan->Init.ProtocolException = ENABLE;
|
11 | hfdcan->Init.NominalPrescaler = g_astcBaudratesCAN[ baudrateindex ].prescaler;
|
12 | hfdcan->Init.NominalSyncJumpWidth = 1;
|
13 | hfdcan->Init.NominalTimeSeg1 = g_astcBaudratesCAN[ baudrateindex ].BS1;
|
14 | hfdcan->Init.NominalTimeSeg2 = g_astcBaudratesCAN[ baudrateindex ].BS2;
|
15 | hfdcan->Init.DataPrescaler = g_astcBaudratesCAN[ baudrateindex ].prescaler;
|
16 | hfdcan->Init.DataSyncJumpWidth = 1;
|
17 | hfdcan->Init.DataTimeSeg1 = g_astcBaudratesCAN[ baudrateindex ].BS1;;
|
18 | hfdcan->Init.DataTimeSeg2 = g_astcBaudratesCAN[ baudrateindex ].BS2;;
|
19 |
|
20 | hfdcan->Init.TxFifoQueueMode = FDCAN_TX_FIFO_OPERATION;
|
21 |
|
22 | /* prepare the acceptance filter, the filter itself will be setup afterwards */
|
23 | hfdcan->Init.StdFiltersNbr = 28;
|
24 | hfdcan->Init.ExtFiltersNbr = 8;
|
25 |
|
26 | status = HAL_FDCAN_Init( hfdcan );
|
27 |
|
28 | if (status == HAL_OK)
|
29 | status = HAL_FDCAN_EnableTxDelayCompensation(hfdcan);
|
30 |
|
31 | return status;
|
32 | }
|
Im Tx-Buffer sind alle 3 Nachrichten identisch und sind auf AE78, AEC0
und AF08 zu finden
1 | 0x4000ae00 : 0x4000AE00 <Hex>
|
2 | Address 0 - 3 4 - 7 8 - B C - F
|
3 | 4000AE60 00000000 00000000 00000000 00000000
|
4 | 4000AE70 00000000 00000000 00008C04 00000200
|
5 | 4000AE80 AA140000 00000000 00000000 00000000
|
6 | 4000AE90 00000000 00000000 00000000 00000000
|
7 | 4000AEA0 00000000 00000000 00000000 00000000
|
8 | 4000AEB0 00000000 00000000 00000000 00000000
|
9 | 4000AEC0 00008C04 00000200 AA150000 00000000
|
10 | 4000AED0 00000000 00000000 00000000 00000000
|
11 | 4000AEE0 00000000 00000000 00000000 00000000
|
12 | 4000AEF0 00000000 00000000 00000000 00000000
|
13 | 4000AF00 00000000 00000000 00008C04 00000200
|
14 | 4000AF10 AA130000 00000000 00000000 00000000
|
15 | 4000AF20 00000000 00000000 00000000 00000000
|
16 | 4000AF30 00000000 00000000 00000000 00000000
|