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! :-)
Du hast schon einen zweiten CAN-Knoten im normal mode am Bus und alles korrekt terminiert?
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>© 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
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.
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?
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
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
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!
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
Da hilft es oftmals nur in die HAL (und Ref Man) reinzuschauen und sich die Definitionen selbst zu suchen.
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...
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
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...
Und noch was: Damit du den Filter nutzen kannst, musst du natürlich auch diesen definieren:
1 | hfdcan1.Init.ExtFiltersNbr = 1; |
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
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...
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 :-)
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!
Falk B. schrieb: > Der gehört in den ANHANG, siehe Netiquette! Das Thema ist ein Jahr alt und hat sich mittlerweile ERLEDIGT...
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?
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.