Forum: Mikrocontroller und Digitale Elektronik STM32 sendet nicht im CAN-Mode "Normal"


von Daniel F. (lmdaniel999)


Angehängte Dateien:

Lesenswert?

Hallo zusammen!

Ich habe eine Frage zum STM32H753 Controller mit CAN-FD.

Dieser sendet im im External Loopback Modus ganz normal. Ich kann Daten 
senden und empfange meine eigenen Nachrichten. Die gesendeten 
Nachrichten sehe ich korrekt in einem CAN-FD-Logger.

Beim Umschalten auf den Modus "Normal" sendet der µC nicht mehr. Ich 
sehe im Logik-Analyzer auf der TX Leitung nur, dass diese auf Low 
gezogen wird, kurz drauf wieder High. Der Logger meldet dann einen 
Stuff-Bit-Error, was ja eine logische Konsequenz ist.

Wieder umgeschaltet auf External Loopback und alles läuft...

Was kann das sein?

Vielen Dank! :-)

von Guest (Gast)


Lesenswert?

Code....?

von Domenik (Gast)


Lesenswert?

Schaltplan.... ?

von rcc (Gast)


Lesenswert?

Du hast schon einen zweiten CAN-Knoten im normal mode am Bus und alles 
korrekt terminiert?

von Daniel F. (lmdaniel999)


Lesenswert?

Hi,

zum Schaltplan: Es ist ein original STM32H753I-EVAL2 mit 
CAN-FD-Schnittstelle.

zum Code:
1
/* USER CODE BEGIN Header */
2
/**
3
  ******************************************************************************
4
  * @file           : main.c
5
  * @brief          : Main program body
6
  ******************************************************************************
7
  * @attention
8
  *
9
  * <h2><center>&copy; Copyright (c) 2020 STMicroelectronics.
10
  * All rights reserved.</center></h2>
11
  *
12
  * This software component is licensed by ST under BSD 3-Clause license,
13
  * the "License"; You may not use this file except in compliance with the
14
  * License. You may obtain a copy of the License at:
15
  *                        opensource.org/licenses/BSD-3-Clause
16
  *
17
  ******************************************************************************
18
  */
19
/* USER CODE END Header */
20
21
/* Includes ------------------------------------------------------------------*/
22
#include "main.h"
23
24
/* Private includes ----------------------------------------------------------*/
25
/* USER CODE BEGIN Includes */
26
/* USER CODE END Includes */
27
28
/* Private typedef -----------------------------------------------------------*/
29
/* USER CODE BEGIN PTD */
30
31
/* USER CODE END PTD */
32
33
/* Private define ------------------------------------------------------------*/
34
/* USER CODE BEGIN PD */
35
/* USER CODE END PD */
36
37
/* Private macro -------------------------------------------------------------*/
38
/* USER CODE BEGIN PM */
39
40
/* USER CODE END PM */
41
42
/* Private variables ---------------------------------------------------------*/
43
44
FDCAN_HandleTypeDef hfdcan1;
45
46
/* USER CODE BEGIN PV */
47
FDCAN_TxHeaderTypeDef TxHeader;
48
FDCAN_RxHeaderTypeDef RxHeader;
49
FDCAN_FilterTypeDef sFilterConfig;
50
uint8_t TxData[8] = {0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48};
51
uint8_t RxData[8];
52
/* USER CODE END PV */
53
54
/* Private function prototypes -----------------------------------------------*/
55
void SystemClock_Config(void);
56
static void MX_GPIO_Init(void);
57
static void MX_FDCAN1_Init(void);
58
/* USER CODE BEGIN PFP */
59
60
/* USER CODE END PFP */
61
62
/* Private user code ---------------------------------------------------------*/
63
/* USER CODE BEGIN 0 */
64
65
/* USER CODE END 0 */
66
67
/**
68
  * @brief  The application entry point.
69
  * @retval int
70
  */
71
int main(void)
72
{
73
  /* USER CODE BEGIN 1 */
74
75
  /* USER CODE END 1 */
76
77
  /* MCU Configuration--------------------------------------------------------*/
78
79
  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
80
  HAL_Init();
81
82
  /* USER CODE BEGIN Init */
83
84
  /* USER CODE END Init */
85
86
  /* Configure the system clock */
87
  SystemClock_Config();
88
89
  /* USER CODE BEGIN SysInit */
90
91
  /* USER CODE END SysInit */
92
93
  /* Initialize all configured peripherals */
94
  MX_GPIO_Init();
95
  MX_FDCAN1_Init();
96
  /* USER CODE BEGIN 2 */
97
  /* USER CODE END 2 */
98
99
  /* Infinite loop */
100
  /* USER CODE BEGIN WHILE */
101
102
  /* Start the FDCAN module */
103
  if (HAL_FDCAN_Start(&hfdcan1) != HAL_OK)
104
  {
105
    // Show Error on Display
106
    while (1) {};
107
  }
108
109
110
  /* Configure Tx buffer message */
111
  TxHeader.Identifier = 0x12345678;
112
  TxHeader.IdType = FDCAN_EXTENDED_ID;
113
  TxHeader.TxFrameType = FDCAN_DATA_FRAME;
114
  TxHeader.DataLength = FDCAN_DLC_BYTES_8;
115
  TxHeader.ErrorStateIndicator = FDCAN_ESI_PASSIVE;
116
  TxHeader.BitRateSwitch = FDCAN_BRS_ON;
117
  TxHeader.FDFormat = FDCAN_FD_CAN;
118
  TxHeader.TxEventFifoControl = FDCAN_STORE_TX_EVENTS;
119
  TxHeader.MessageMarker = 0x00;
120
121
  if (HAL_FDCAN_AddMessageToTxFifoQ(&hfdcan1, &TxHeader, TxData) != HAL_OK)
122
  {
123
    // Show Error on Display
124
    while (1) {};
125
  }
126
127
128
  HAL_Delay(1000);
129
130
  while (1)
131
  {
132
133
    if (HAL_FDCAN_IsRxBufferMessageAvailable(&hfdcan1, FDCAN_RX_BUFFER0))
134
    {
135
        if (HAL_FDCAN_GetRxMessage(&hfdcan1, FDCAN_RX_BUFFER0, &RxHeader, RxData) != HAL_OK)
136
      {
137
          // Show Error on Display
138
        while (1) {};
139
      }
140
141
        // Show Message on Display
142
143
    }
144
    else
145
    {
146
         // No Message
147
    }
148
149
    /* USER CODE END WHILE */
150
151
    /* USER CODE BEGIN 3 */
152
  }
153
  /* USER CODE END 3 */
154
}
155
156
/**
157
  * @brief System Clock Configuration
158
  * @retval None
159
  */
160
void SystemClock_Config(void)
161
{
162
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
163
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
164
  RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
165
166
  /** Supply configuration update enable 
167
  */
168
  HAL_PWREx_ConfigSupply(PWR_LDO_SUPPLY);
169
  /** Configure the main internal regulator output voltage 
170
  */
171
  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
172
173
  while(!__HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY)) {}
174
  /** Macro to configure the PLL clock source 
175
  */
176
  __HAL_RCC_PLL_PLLSOURCE_CONFIG(RCC_PLLSOURCE_HSE);
177
  /** Initializes the CPU, AHB and APB busses clocks 
178
  */
179
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
180
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
181
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
182
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
183
  RCC_OscInitStruct.PLL.PLLM = 5;
184
  RCC_OscInitStruct.PLL.PLLN = 160;
185
  RCC_OscInitStruct.PLL.PLLP = 2;
186
  RCC_OscInitStruct.PLL.PLLQ = 4;
187
  RCC_OscInitStruct.PLL.PLLR = 2;
188
  RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_2;
189
  RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1VCOWIDE;
190
  RCC_OscInitStruct.PLL.PLLFRACN = 0;
191
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
192
  {
193
    Error_Handler();
194
  }
195
  /** Initializes the CPU, AHB and APB busses clocks 
196
  */
197
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
198
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2
199
                              |RCC_CLOCKTYPE_D3PCLK1|RCC_CLOCKTYPE_D1PCLK1;
200
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
201
  RCC_ClkInitStruct.SYSCLKDivider = RCC_SYSCLK_DIV1;
202
  RCC_ClkInitStruct.AHBCLKDivider = RCC_HCLK_DIV2;
203
  RCC_ClkInitStruct.APB3CLKDivider = RCC_APB3_DIV2;
204
  RCC_ClkInitStruct.APB1CLKDivider = RCC_APB1_DIV2;
205
  RCC_ClkInitStruct.APB2CLKDivider = RCC_APB2_DIV2;
206
  RCC_ClkInitStruct.APB4CLKDivider = RCC_APB4_DIV2;
207
208
  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
209
  {
210
    Error_Handler();
211
  }
212
  PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_FDCAN;
213
  PeriphClkInitStruct.PLL2.PLL2M = 5;
214
  PeriphClkInitStruct.PLL2.PLL2N = 160;
215
  PeriphClkInitStruct.PLL2.PLL2P = 2;
216
  PeriphClkInitStruct.PLL2.PLL2Q = 10;
217
  PeriphClkInitStruct.PLL2.PLL2R = 2;
218
  PeriphClkInitStruct.PLL2.PLL2RGE = RCC_PLL2VCIRANGE_2;
219
  PeriphClkInitStruct.PLL2.PLL2VCOSEL = RCC_PLL2VCOWIDE;
220
  PeriphClkInitStruct.PLL2.PLL2FRACN = 0;
221
  PeriphClkInitStruct.FdcanClockSelection = RCC_FDCANCLKSOURCE_PLL2;
222
  if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
223
  {
224
    Error_Handler();
225
  }
226
}
227
228
/**
229
  * @brief FDCAN1 Initialization Function
230
  * @param None
231
  * @retval None
232
  */
233
static void MX_FDCAN1_Init(void)
234
{
235
236
  /* USER CODE BEGIN FDCAN1_Init 0 */
237
238
  /* USER CODE END FDCAN1_Init 0 */
239
240
  /* USER CODE BEGIN FDCAN1_Init 1 */
241
  /* USER CODE END FDCAN1_Init 1 */
242
  hfdcan1.Instance = FDCAN1;
243
  hfdcan1.Init.FrameFormat = FDCAN_FRAME_FD_BRS;
244
  hfdcan1.Init.Mode = FDCAN_MODE_NORMAL;
245
  hfdcan1.Init.AutoRetransmission = DISABLE;
246
  hfdcan1.Init.TransmitPause = DISABLE;
247
  hfdcan1.Init.ProtocolException = DISABLE;
248
  hfdcan1.Init.NominalPrescaler = 8;
249
  hfdcan1.Init.NominalSyncJumpWidth = 1;
250
  hfdcan1.Init.NominalTimeSeg1 = 13;
251
  hfdcan1.Init.NominalTimeSeg2 = 6;
252
  hfdcan1.Init.DataPrescaler = 2;
253
  hfdcan1.Init.DataSyncJumpWidth = 1;
254
  hfdcan1.Init.DataTimeSeg1 = 13;
255
  hfdcan1.Init.DataTimeSeg2 = 6;
256
  hfdcan1.Init.MessageRAMOffset = 0;
257
  hfdcan1.Init.StdFiltersNbr = 0;
258
  hfdcan1.Init.ExtFiltersNbr = 1;
259
  hfdcan1.Init.RxFifo0ElmtsNbr = 0;
260
  hfdcan1.Init.RxFifo0ElmtSize = FDCAN_DATA_BYTES_8;
261
  hfdcan1.Init.RxFifo1ElmtsNbr = 0;
262
  hfdcan1.Init.RxFifo1ElmtSize = FDCAN_DATA_BYTES_8;
263
  hfdcan1.Init.RxBuffersNbr = 1;
264
  hfdcan1.Init.RxBufferSize = FDCAN_DATA_BYTES_8;
265
  hfdcan1.Init.TxEventsNbr = 1;
266
  hfdcan1.Init.TxBuffersNbr = 0;
267
  hfdcan1.Init.TxFifoQueueElmtsNbr = 1;
268
  hfdcan1.Init.TxFifoQueueMode = FDCAN_TX_FIFO_OPERATION;
269
  hfdcan1.Init.TxElmtSize = FDCAN_DATA_BYTES_8;
270
  if (HAL_FDCAN_Init(&hfdcan1) != HAL_OK)
271
  {
272
    Error_Handler();
273
  }
274
  /* USER CODE BEGIN FDCAN1_Init 2 */
275
276
  /* Configure extended ID reception filter to Rx FIFO 1 */
277
  sFilterConfig.IdType = FDCAN_EXTENDED_ID;
278
  sFilterConfig.FilterIndex = 0;
279
  sFilterConfig.FilterType = FDCAN_FILTER_DUAL;
280
  sFilterConfig.FilterConfig = FDCAN_FILTER_TO_RXBUFFER;
281
  sFilterConfig.FilterID1 = 0x12345678;
282
  sFilterConfig.FilterID2 = 0x12345680;
283
  sFilterConfig.RxBufferIndex = 0;
284
    if (HAL_FDCAN_ConfigFilter(&hfdcan1, &sFilterConfig) != HAL_OK)
285
  {
286
    Error_Handler();
287
  }
288
  /* USER CODE END FDCAN1_Init 2 */
289
290
}
291
292
/**
293
  * @brief GPIO Initialization Function
294
  * @param None
295
  * @retval None
296
  */
297
static void MX_GPIO_Init(void)
298
{
299
  GPIO_InitTypeDef GPIO_InitStruct = {0};
300
301
  /* GPIO Ports Clock Enable */
302
  __HAL_RCC_GPIOK_CLK_ENABLE();
303
  __HAL_RCC_GPIOB_CLK_ENABLE();
304
  __HAL_RCC_GPIOJ_CLK_ENABLE();
305
  __HAL_RCC_GPIOA_CLK_ENABLE();
306
  __HAL_RCC_GPIOI_CLK_ENABLE();
307
  __HAL_RCC_GPIOH_CLK_ENABLE();
308
  __HAL_RCC_GPIOF_CLK_ENABLE();
309
310
  /*Configure GPIO pin Output Level */
311
  HAL_GPIO_WritePin(LED_GREEN_GPIO_Port, LED_GREEN_Pin, GPIO_PIN_RESET);
312
313
  /*Configure GPIO pins : PK5 PK4 PK6 PK3 
314
                           PK2 PK0 PK1 */
315
  GPIO_InitStruct.Pin = GPIO_PIN_5|GPIO_PIN_4|GPIO_PIN_6|GPIO_PIN_3 
316
                          |GPIO_PIN_2|GPIO_PIN_0|GPIO_PIN_1;
317
  GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
318
  GPIO_InitStruct.Pull = GPIO_NOPULL;
319
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
320
  GPIO_InitStruct.Alternate = GPIO_AF14_LTDC;
321
  HAL_GPIO_Init(GPIOK, &GPIO_InitStruct);
322
323
  /*Configure GPIO pins : PB6 PB7 */
324
  GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7;
325
  GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
326
  GPIO_InitStruct.Pull = GPIO_NOPULL;
327
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
328
  GPIO_InitStruct.Alternate = GPIO_AF4_I2C1;
329
  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
330
331
  /*Configure GPIO pins : PJ15 PJ12 PJ11 PJ10 
332
                           PJ9 PJ0 PJ6 PJ5 
333
                           PJ2 PJ3 PJ4 */
334
  GPIO_InitStruct.Pin = GPIO_PIN_15|GPIO_PIN_12|GPIO_PIN_11|GPIO_PIN_10 
335
                          |GPIO_PIN_9|GPIO_PIN_0|GPIO_PIN_6|GPIO_PIN_5 
336
                          |GPIO_PIN_2|GPIO_PIN_3|GPIO_PIN_4;
337
  GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
338
  GPIO_InitStruct.Pull = GPIO_NOPULL;
339
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
340
  GPIO_InitStruct.Alternate = GPIO_AF14_LTDC;
341
  HAL_GPIO_Init(GPIOJ, &GPIO_InitStruct);
342
343
  /*Configure GPIO pins : PI12 PI13 PI14 PI15 */
344
  GPIO_InitStruct.Pin = GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15;
345
  GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
346
  GPIO_InitStruct.Pull = GPIO_NOPULL;
347
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
348
  GPIO_InitStruct.Alternate = GPIO_AF14_LTDC;
349
  HAL_GPIO_Init(GPIOI, &GPIO_InitStruct);
350
351
  /*Configure GPIO pin : LED_GREEN_Pin */
352
  GPIO_InitStruct.Pin = LED_GREEN_Pin;
353
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
354
  GPIO_InitStruct.Pull = GPIO_NOPULL;
355
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
356
  HAL_GPIO_Init(LED_GREEN_GPIO_Port, &GPIO_InitStruct);
357
358
}
359
360
/* USER CODE BEGIN 4 */
361
362
/* USER CODE END 4 */
363
364
/**
365
  * @brief  This function is executed in case of error occurrence.
366
  * @retval None
367
  */
368
void Error_Handler(void)
369
{
370
  /* USER CODE BEGIN Error_Handler_Debug */
371
  /* User can add his own implementation to report the HAL error return state */
372
373
  /* USER CODE END Error_Handler_Debug */
374
}
375
376
#ifdef  USE_FULL_ASSERT
377
/**
378
  * @brief  Reports the name of the source file and the source line number
379
  *         where the assert_param error has occurred.
380
  * @param  file: pointer to the source file name
381
  * @param  line: assert_param error line source number
382
  * @retval None
383
  */
384
void assert_failed(uint8_t *file, uint32_t line)
385
{ 
386
  /* USER CODE BEGIN 6 */
387
  /* User can add his own implementation to report the file name and line number,
388
     tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
389
  /* USER CODE END 6 */
390
}
391
#endif /* USE_FULL_ASSERT */
392
393
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

Am Bus hängt aktuell ein zweites Node und ein Logger.
Das zweite Node antwortet auch immer schön brav auf die Nachrichten, die 
der STM im External-Loopback-Mode sendet. Das sehe ich im Logger.
Der Logger selbst bestätigt wohl auch den Nachrichtenempfang...

Ich finde komisch, dass die TX Leitung zwischen µC und Bus-Treiber nur 
auf Low geht und sonst nix macht....

EDIT: Terminierung passt auch. Da hab ich sogar auch einiges getestet!

: Bearbeitet durch User
von Domenik (Gast)


Lesenswert?

Daniel F. schrieb:
> Es ist ein original STM32H753I-EVAL2 mit CAN-FD-Schnittstelle.

Mit nur EINEM Bord bekommst Du kein Ausfahrsignal. CAN funktioniert 
immer nur mit >1 Teilnehmern. Lies dir erstmal die Spezifikation an, wie 
der Bus funktioniert.

von Domenik (Gast)


Lesenswert?

Daniel F. schrieb:
> Am Bus hängt aktuell ein zweites Node und ein Logger.
> Das zweite Node antwortet auch immer schön brav auf die Nachrichten, die
> der STM im External-Loopback-Mode sendet. Das sehe ich im Logger.
> Der Logger selbst bestätigt wohl auch den Nachrichtenempfang...
>
> Ich finde komisch, dass die TX Leitung zwischen µC und Bus-Treiber nur
> auf Low geht und sonst nix macht....
>
> EDIT: Terminierung passt auch. Da hab ich sogar auch einiges getestet!

Sry, leider zu spät gesehen. Das ist merkwürdig. Der Logger ist auch als 
aktiver Teilnehmer geschaltet? Was antwortet Node2? Nur das Ack oder 
eine Nachricht? Befindet sich Node2 im normalen Modus?

von Christian K. (the_kirsch)


Lesenswert?

Wenn du keinen anderen Teilnehmer hast, muss die RX Leitung die gleichen 
Logik-Pegel bekommen wie die TX Leitung. Und Software-Seitig müsstest du 
als Folge daraus einen Missing ACT Fehler bekommen.

Ansonsten ist was an deinem MCP2562FD kaputt oder der Rx-Pin am STM ist 
falsch konfiguriert.

: Bearbeitet durch User
von Daniel F. (lmdaniel999)


Lesenswert?

Domenik schrieb:
> Das ist merkwürdig. Der Logger ist auch als
> aktiver Teilnehmer geschaltet? Was antwortet Node2? Nur das Ack oder
> eine Nachricht? Befindet sich Node2 im normalen Modus?

Der Logger sollte antworten, da er nicht inaktiv ist. Ich kann ja auch 
mit ihm senden. Der "Silent-Mode" ist nicht an. Allerdings kommt die 
Nachricht ja schon nicht an, daher kommt kein ACK.

Node 2 antwortet mit einer Nachricht. Genaueres kann ich dazu nicht 
sagen. Das ist ein fertiges Gerät. Die Antwort sehe ich aber nur auf dem 
Logger, da der STM ja im External-Loop-Mode ist.

Christian K. schrieb:
> Wenn du keinen anderen Teilnehmer hast, muss die RX Leitung die gleichen
> Logik-Pegel bekommen wie die TX Leitung. Und Software-Seitig müsstest du
> als Folge daraus einen Missing ACT Fehler bekommen.
>
> Ansonsten ist was an deinem MCP2562FD kaputt oder der Rx-Pin am STM ist
> falsch konfiguriert.

Dass der kaputt oder falsch konfiguriert ist, schließe ich aus.
Ich kann ja senden und bekomme die Antworten aus dem externen Loopback.
Daher passt RX und TX am µC schonmal.

Der MCP ist ja "nur" ein Logikwandler, oder hat der noch einen Puffer 
intern?
Was passiert denn beim MCP, wenn er nach dem ersten Bit erkennt, dass er 
den BUS nicht auf LOW treiben kann. Der High Pegel ist ja dominant. Wenn 
der RX diesem nicht folgt, hört der µC dann sofort mit dem Senden auf?
Das könnte das Verhalten erklären...

EDIT: Der internal Loopback bleibt ja im STM, der external Loopback geht 
durch den MCP, oder?

: Bearbeitet durch User
von Daniel F. (lmdaniel999)


Lesenswert?

ERLEDIGT!

Habe das Problem gelöst:

Nachdem ich die neue Platine nun bestückt habe und alles funktioniert, 
hab ich nochmal genauer nachgesucht.
Auf dem EVAL Board ist ein offener Jumper in der RX Leitung.

Deshalb hat der µC nicht weiter gesendet, weil er vermutlich dachte, 
dass auf dem Bus eine dominante Kommunikation läuft.

Gesehen habe ich das nicht, weil der Jumper nicht auf der 
Schaltplanseite mit der CAN-Schnittstelle ist, sondern auf der 
"Hauptseite" des µC. Beim CAN steht aber der PIN vom µC an der Leitung, 
daher dachte ich, dass der direkt dahin geht...

Also: Problem gelöst! Zur Fehlersuche hätte ich RX und TX mit einem 
Logikanalysator vergleichen sollen, wie hier vorgeschlagen wurde! Danke 
an alle Beteiligten!

von Thommy (Gast)


Lesenswert?

Hallo zusammen,

ich wollte mich an dem Projekt von Danie F. orientieren und mit meinen 
STM32G4 eine CAN Comunikation aufbauen. Ich nutze den FDCAN Bus 2 auf 
der MCU. Leider bekomme ich einige Errors wenn ich den oben gezeigten 
Code nutze:

z.B.:
1
../Core/Src/main.c:152:56: error: 'FDCAN_RX_BUFFER0' undeclared (first use in this function); did you mean 'FDCAN_TX_BUFFER0'?
2
     if (HAL_FDCAN_IsRxBufferMessageAvailable(&hfdcan2, FDCAN_RX_BUFFER0))
oder
1
../Core/Src/main.c:251:15: error: 'FDCAN_InitTypeDef {aka struct <anonymous>}' has no member named 'MessageRAMOffset'
2
   hfdcan2.Init.MessageRAMOffset = 0;

Da ich noch recht neu im Thema STM32 bin waere ich ueber einige Tipps 
ehr dankbar,

thx and cya Thommy

von Domenik (Gast)


Lesenswert?

Da hilft es oftmals nur in die HAL (und Ref Man) reinzuschauen und sich 
die Definitionen selbst zu suchen.

von Daniel F. (lmdaniel999)


Lesenswert?

Hi.
Das wird nicht funktionieren, wenn du einfach den Code oben kopierst.
Der Code wurde mit dem "Konfigurator" der STM32CubeIDE erstellt und dann 
ergänzt.

Du solltest auch den Konfigurator nutzen, dort eine Config mit deinem 
Board erstellen und dann lediglich die main abändern.

Zu der Cube IDE findest du Tutorials, die dir eine "Grundkonfig" 
ermöglichen. Der Rest ist ausprobieren.

Leider sind die Beispiele von ST anders erstellt und so kann man das mit 
dem Konfigurator nicht so gut nachvollziehen...

von Thommy (Gast)


Lesenswert?

Hallo Domenik, hallo Daniel ,

danke fuer die schnelle Antworten. Ich hab mit i der STM32CubeIDE ein 
passendes Projekt erstellt und auch in der ICO File den FD CAN Bus als 
Connectivity FDCAN2 definiert. Daraus hat die IDE auch meinen Code 
generiert mit dem das Senden auch geklappt hat. Leider bekomm ich dann 
als ich den Code mit dem vom Daniel ergänzt habe der Fehler im RX 
Bereich.

Soll heissen, dass die Funktion MX_FDCAN2_Init() automatisch generiert 
wurde. Allerdings nicht so umfangreich wie im oben gezeigten Code
1
/**
2
  * @brief FDCAN2 Initialization Function
3
  * @param None
4
  * @retval None
5
  */
6
static void MX_FDCAN2_Init(void)
7
{
8
FDCAN_FilterTypeDef sFilterConfig;
9
10
  /* USER CODE BEGIN FDCAN2_Init 0 */
11
12
  /* USER CODE END FDCAN2_Init 0 */
13
14
  /* USER CODE BEGIN FDCAN2_Init 1 */
15
16
  /* USER CODE END FDCAN2_Init 1 */
17
  hfdcan2.Instance = FDCAN2;
18
  hfdcan2.Init.FrameFormat = FDCAN_FRAME_FD_NO_BRS;
19
  hfdcan2.Init.Mode = FDCAN_MODE_NORMAL;
20
  hfdcan2.Init.AutoRetransmission = DISABLE;
21
  hfdcan2.Init.TransmitPause = DISABLE;
22
  hfdcan2.Init.ProtocolException = DISABLE;
23
  hfdcan2.Init.NominalPrescaler = 1;
24
  hfdcan2.Init.NominalSyncJumpWidth = 1;
25
  hfdcan2.Init.NominalTimeSeg1 = 2;
26
  hfdcan2.Init.NominalTimeSeg2 = 2;
27
  hfdcan2.Init.DataPrescaler = 1;
28
  hfdcan2.Init.DataSyncJumpWidth = 1;
29
  hfdcan2.Init.DataTimeSeg1 = 1;
30
  hfdcan2.Init.DataTimeSeg2 = 1;
31
  hfdcan2.Init.StdFiltersNbr = 0;
32
  hfdcan2.Init.ExtFiltersNbr = 0;
33
  hfdcan2.Init.TxFifoQueueMode = FDCAN_TX_FIFO_OPERATION;
34
  if (HAL_FDCAN_Init(&hfdcan2) != HAL_OK)
35
  {
36
    Error_Handler();
37
  }
38
  /* USER CODE BEGIN FDCAN2_Init 2 */
39
40
  /* USER CODE END FDCAN2_Init 2 */
41
42
}

und ich wollte nur das Empfangen ergaenzen was leider nicht wirklich 
funktioniert. Danke fuer eure hilfe.

Thx and cya Thommy

von Daniel F. (lmdaniel999)


Angehängte Dateien:

Lesenswert?

Hi,

es gibt verschiedene Einstellungen, wie du senden und empfangen kannst.
Du musst eine passende Einstellung für das Empfangen wählen. So wie ich 
das sehe hast du nur das Senden aktiviert.

Um zu Empfangen musst du Filter anlegen. Diese Filter bestimmen dann, 
welche Nachrichten (von welchen IDs) empfangen werden und was mit diesen 
passiert:
1
  /* Configure extended ID reception filter to Rx FIFO 1 */
2
  sFilterConfig.IdType = FDCAN_EXTENDED_ID;
3
  sFilterConfig.FilterIndex = 0;
4
  sFilterConfig.FilterType = FDCAN_FILTER_DUAL;
5
  sFilterConfig.FilterConfig = FDCAN_FILTER_TO_RXBUFFER;
6
  sFilterConfig.FilterID1 = 0x12345678;
7
  sFilterConfig.FilterID2 = 0x12345680;
8
  sFilterConfig.RxBufferIndex = 0;

Damit der Filter aber die Nachrichten in den RXBUFFER schreiben kann, 
musst du den Buffer erstellen. Das ist bei mir diese Codezeile:
1
  hfdcan1.Init.RxBuffersNbr = 1;
2
  hfdcan1.Init.RxBufferSize = FDCAN_DATA_BYTES_8;

Das kannst du im Konfigurator bei FDCAN einstellen. Anbei dazu ein Bild.

Wenn der Buffer nicht deklariert wurde, dann ist klar, dass es zum 
Fehler kommt...

von Daniel F. (lmdaniel999)


Lesenswert?

Und noch was:
Damit du den Filter nutzen kannst, musst du natürlich auch diesen 
definieren:
1
hfdcan1.Init.ExtFiltersNbr = 1;

von Thommy (Gast)


Angehängte Dateien:

Lesenswert?

Hi Danile,

danke fuer deine Unterstuetzung. Leider steh ich etwas auf dem schlauch. 
Bei mir sieht die Konfiguration doch etwas anders aus und der RX Buffer 
ist nicht vorhanden (sieh Bild).
Kann es sein, dass die API fuer den STM32G4 den FDCAN noch nicht 
vollstaendig unterstuetzt? (Quelle: 
https://forums.mbed.com/t/fdcan-support-for-stm32g474-nucleo/9924)

Thx and cya Thommy

von Daniel F. (lmdaniel999)


Lesenswert?

Hi,

ob der G4 das unterstützt, keine Ahnung.
Sollte aber doch in der Doku nachzulesen sein...

Die Filter kannst du ja aktivieren.
Und irgendwie muss der ja auch empfangen können.

Schau dir doch mal die Application Notes zu dem Prozessor an...

von Recently (Gast)


Lesenswert?

Vielen Dank für diesen Beitrag. Habe 2 Tage mit dem CAN-FD-Problem 
verschwendet und am Ende war es nun der hier beschriebene Jumper. Ohne 
diesen Beitrag würde ich wahrscheinlich immer noch suchen :-)

von Falk B. (falk)


Lesenswert?

Daniel F. schrieb:
> zum Schaltplan: Es ist ein original STM32H753I-EVAL2 mit
> CAN-FD-Schnittstelle.
>
> zum Code:

Der gehört in den ANHANG, siehe Netiquette!

von Daniel F. (lmdaniel999)


Lesenswert?

Falk B. schrieb:
> Der gehört in den ANHANG, siehe Netiquette!

Das Thema ist ein Jahr alt und hat sich mittlerweile ERLEDIGT...

von Falk B. (falk)


Lesenswert?

Daniel F. schrieb:
>> Der gehört in den ANHANG, siehe Netiquette!
>
> Das Thema ist ein Jahr alt und hat sich mittlerweile ERLEDIGT...

Ja, ich hatte das Datum übersehen. Trotzdem ist die Aussage richtig, 
vielleicht heherzigt es ja Einer beim nächsten Mal. Vielleicht sogar DU?

von Rolf M. (rmagnus)


Lesenswert?

Mann muss das übrigens gar nicht unter Netiquette suchen. Es reicht 
schon, die Regeln unter "Wichtige Regeln - erst lesen, dann posten!" zu 
lesen, bevor man postet.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.