Hallo Zusammen,
Ich kämpfe seit einiger Zeit damit, den CAN-Bus auf meinen zwei
Evalboards (STM32H745I-DISCO) zum Laufen zu bringen. Um das ganze zu
testen möchte ich, dass das eine Evalboard dem anderen eine Nachricht
sendet. Die Abschlusswiderstände habe durch setzen der Jumper
berücksichtigt. Die beiden Evalbaords habe ich jeweils über CAN-High und
CAN-Low mit einander verbunden.
Das Problem: Ich komme gar nicht erst soweit, dass ich was senden kann:
Egal wie ich den CAN-Bus in CubeMX konfiguriere, das Programm springt
immer in den folgenden Fehlerabschnitt, in dem anscheinend geprüft wird
ob dem TX FIFO Speicher im RAM zugewiesen wurden ist (zumindest steht es
so im Kommentar):
1 | /* Check that the Tx FIFO/Queue has an allocated area into the RAM */
|
2 | if ((hfdcan->Instance->TXBC & FDCAN_TXBC_TFQS) == 0U)
|
3 | {
|
4 | /* Update error code */
|
5 | hfdcan->ErrorCode |= HAL_FDCAN_ERROR_PARAM;
|
6 |
|
7 | return HAL_ERROR;
|
8 | }
|
Der oben erwähnte Abschnitt kommt aus der stm32h7xx_hal_fdcan.c.
Meine CAN-Bus Konfiguration sieht wie folgt aus. Erst einmal habe ich
das FDCAN Initialisiert:
1 | static void MX_FDCAN1_Init(void)
|
2 | {
|
3 | hfdcan1.Instance = FDCAN1;
|
4 | hfdcan1.Init.FrameFormat = FDCAN_FRAME_CLASSIC;
|
5 | hfdcan1.Init.Mode = FDCAN_MODE_NORMAL;
|
6 | hfdcan1.Init.AutoRetransmission = ENABLE;
|
7 | hfdcan1.Init.TransmitPause = DISABLE;
|
8 | hfdcan1.Init.ProtocolException = DISABLE;
|
9 | hfdcan1.Init.NominalPrescaler = 12;
|
10 | hfdcan1.Init.NominalSyncJumpWidth = 1;
|
11 | hfdcan1.Init.NominalTimeSeg1 = 5;
|
12 | hfdcan1.Init.NominalTimeSeg2 = 2;
|
13 | hfdcan1.Init.DataPrescaler = 12;
|
14 | hfdcan1.Init.DataSyncJumpWidth = 1;
|
15 | hfdcan1.Init.DataTimeSeg1 = 5;
|
16 | hfdcan1.Init.DataTimeSeg2 = 2;
|
17 | hfdcan1.Init.MessageRAMOffset = 0;
|
18 | hfdcan1.Init.StdFiltersNbr = 1;
|
19 | hfdcan1.Init.ExtFiltersNbr = 0;
|
20 | hfdcan1.Init.RxFifo0ElmtsNbr = 16;
|
21 | hfdcan1.Init.RxFifo0ElmtSize = FDCAN_DATA_BYTES_8;
|
22 | hfdcan1.Init.RxFifo1ElmtsNbr = 0;
|
23 | hfdcan1.Init.RxFifo1ElmtSize = FDCAN_DATA_BYTES_8;
|
24 | hfdcan1.Init.RxBuffersNbr = 16;
|
25 | hfdcan1.Init.RxBufferSize = FDCAN_DATA_BYTES_8;
|
26 | hfdcan1.Init.TxEventsNbr = 16;
|
27 | hfdcan1.Init.TxBuffersNbr = 16;
|
28 | hfdcan1.Init.TxFifoQueueElmtsNbr = 16;
|
29 | hfdcan1.Init.TxFifoQueueMode = FDCAN_TX_FIFO_OPERATION;
|
30 | hfdcan1.Init.TxElmtSize = FDCAN_DATA_BYTES_8;
|
31 | if (HAL_FDCAN_Init(&hfdcan1) != HAL_OK)
|
32 | {
|
33 | Error_Handler();
|
34 | }
|
Anschließend kommt die Konfiguration von RX und TX. Abschließend starten
ich den CAN-Bus:
1 | /* Configure Rx filter */
|
2 | sFilterConfig.IdType = FDCAN_STANDARD_ID;
|
3 | sFilterConfig.FilterIndex = 0;
|
4 | sFilterConfig.FilterType = FDCAN_FILTER_MASK;
|
5 | sFilterConfig.FilterConfig = FDCAN_FILTER_TO_RXFIFO0;
|
6 | sFilterConfig.FilterID1 = 0x456;
|
7 | sFilterConfig.FilterID2 = 0x7FF;
|
8 | if (HAL_FDCAN_ConfigFilter(&hfdcan1, &sFilterConfig) != HAL_OK)
|
9 | {
|
10 | Error_Handler();
|
11 | }
|
12 |
|
13 | /* Configure Tx Settings */
|
14 | TxHeader.Identifier = 0x123;
|
15 | TxHeader.IdType = FDCAN_STANDARD_ID;
|
16 | TxHeader.TxFrameType = FDCAN_DATA_FRAME;
|
17 | TxHeader.DataLength = FDCAN_DLC_BYTES_2;
|
18 | TxHeader.ErrorStateIndicator = FDCAN_ESI_ACTIVE;
|
19 | TxHeader.BitRateSwitch = FDCAN_BRS_OFF;
|
20 | TxHeader.FDFormat = FDCAN_CLASSIC_CAN;
|
21 | TxHeader.TxEventFifoControl = FDCAN_NO_TX_EVENTS;
|
22 | TxHeader.MessageMarker = 0;
|
23 |
|
24 | /* Start FDCAN bus */
|
25 | if (HAL_FDCAN_Start(&hfdcan1) != HAL_OK)
|
26 | {
|
27 | Error_Handler();
|
28 | }
|
So weit so gut: bisher habe ich keinen Error zurückbekommen. Scheint als
wäre die Initialisierung und Konfiguration erfolgreich gewesen. Nun
versuche ich eine Nachricht zu senden:
1 | FDCAN_HandleTypeDef hfdcan1;
|
2 | FDCAN_FilterTypeDef sFilterConfig;
|
3 | FDCAN_TxHeaderTypeDef TxHeader;
|
4 | uint8_t TxData[8]={0xCC,0xDD};
|
5 |
|
6 | int main(void)
|
7 | {
|
8 | ...
|
9 |
|
10 | MX_GPIO_Init();
|
11 | MX_FDCAN1_Init();
|
12 |
|
13 | while (1)
|
14 | {
|
15 | if (HAL_FDCAN_AddMessageToTxFifoQ(&hfdcan1, &TxHeader, TxData) != HAL_OK)
|
16 | {
|
17 | Error_Handler();
|
18 | }
|
19 | HAL_Delay(1000);
|
20 | }
|
21 | }
|
Die Funktion
1 | HAL_FDCAN_AddMessageToTxFifoQ
|
springt dann in den Fehlerabschnitt, den ich ganz oben im Thread
erwähnt habe, und liefert einen HAL_ERROR zurück. Was mache ich falsch?
Sieht die Konfiguration des CAN-Bus denn einigermaßen richtig aus oder
liege ich damit schon vollkommen daneben? Der Vollständigkeit halber
habe ich die Quellcodes in den Anhang gepackt.
Würde mich riesig über ein paar nützliche Hinweise und Tipps freuen.
Danke euch im Voraus!