2025-09-12 11:17 AM - last edited on 2025-09-17 5:49 AM by mƎALLEm
Post edited by ST moderator to be inline with the community rules especially with the code sharing. In next time please use </> button to paste your code. Please read this post: How to insert source code.
Hi everyone,
I am working on Classic CAN communication using the STM32H745I-Discovery board with FDCAN2.
My target CAN configuration is 500 Kbps nominal baud rate with a 16 MHz clock.
Below is my initialization code:
static void MX_FDCAN2_Init(void)
{
hfdcan2.Instance = FDCAN2;
hfdcan2.Init.FrameFormat = FDCAN_FRAME_CLASSIC;
hfdcan2.Init.Mode = FDCAN_MODE_NORMAL;
hfdcan2.Init.AutoRetransmission = ENABLE;
hfdcan2.Init.TransmitPause = DISABLE;
hfdcan2.Init.ProtocolException = ENABLE;
// Timing config: 500 Kbps @ 16 MHz
hfdcan2.Init.NominalPrescaler = 1;
hfdcan2.Init.NominalSyncJumpWidth = 1;
hfdcan2.Init.NominalTimeSeg1 = 23;
hfdcan2.Init.NominalTimeSeg2 = 8;
hfdcan2.Init.DataPrescaler = 1;
hfdcan2.Init.DataSyncJumpWidth = 1;
hfdcan2.Init.DataTimeSeg1 = 1;
hfdcan2.Init.DataTimeSeg2 = 1;
hfdcan2.Init.MessageRAMOffset = 0;
hfdcan2.Init.StdFiltersNbr = 1;
hfdcan2.Init.ExtFiltersNbr = 0;
hfdcan2.Init.RxFifo0ElmtsNbr = 1;
hfdcan2.Init.RxFifo0ElmtSize = FDCAN_DATA_BYTES_8;
hfdcan2.Init.TxFifoQueueElmtsNbr = 1;
hfdcan2.Init.TxFifoQueueMode = FDCAN_TX_FIFO_OPERATION;
hfdcan2.Init.TxElmtSize = FDCAN_DATA_BYTES_8;
if (HAL_FDCAN_Init(&hfdcan2) != HAL_OK) Error_Handler();
// Configure filter (accept all standard IDs)
FDCAN_FilterTypeDef filter;
filter.IdType = FDCAN_STANDARD_ID;
filter.FilterIndex = 0;
filter.FilterType = FDCAN_FILTER_MASK;
filter.FilterConfig = FDCAN_FILTER_TO_RXFIFO0;
filter.FilterID1 = 0x000;
filter.FilterID2 = 0x7FF;
HAL_FDCAN_ConfigFilter(&hfdcan2, &filter);
HAL_FDCAN_Start(&hfdcan2);
// Tx header
txHeader.Identifier = 0x123;
txHeader.IdType = FDCAN_STANDARD_ID;
txHeader.TxFrameType = FDCAN_DATA_FRAME;
txHeader.DataLength = FDCAN_DLC_BYTES_8;
txHeader.BitRateSwitch = FDCAN_BRS_OFF;
txHeader.FDFormat = FDCAN_CLASSIC_CAN;
txHeader.TxEventFifoControl = FDCAN_NO_TX_EVENTS;
txHeader.MessageMarker = 0;
}
And the send function:
HAL_StatusTypeDef CAN_Send(uint8_t* data)
{
if (HAL_FDCAN_AddMessageToTxFifoQ(&hfdcan2, &txHeader, data) == HAL_OK)
{
return HAL_OK;
}
else
{
return HAL_ERROR;
}
}
Issue:
The first few CAN frames transmit successfully.
After that, the TXFIFO becomes full and no further frames are sent.
Sometimes it transmits several messages before stopping, sometimes only one or two.
What I tried so far:
Increased TxFifoQueueElmtsNbr (tried more than 1).
Verified hardware connections and ensured 120Ω termination resistor is present.
Tested the receiver side (looped with another working board), and confirmed reception is fine there.
Tried with both AutoRetransmission enabled/disabled.
Verified the 500 Kbps baud rate configuration with 16 MHz clock.
Still, the issue persists.
Any guidance or working examples would be very helpful.
Thanks!
Solved! Go to Solution.
2025-09-19 3:30 AM
I tested using the HSE with an external crystal (Ref. below image), but the issue still persists.
2025-09-19 3:37 AM
@Sumithra wrote:
I tested using the HSE with an external crystal (Ref. below image), but the issue still persists.
Even if the issue still persist, please keep that configuration.
To avoid unnecessary ping pongs, better to share your project so we can help you efficiently.
2025-09-21 11:39 PM
2025-09-21 11:48 PM
> Issue:
> The first few CAN frames transmit successfully.
No you don't.
Read the CAN specification, you cannot force a transmission on the CAN bus.
First, you can add a message to a queue (or Tx buffer), but the CAN peripheral only transmits it when the bus is free.
And second, the CAN peripheral will retry until the transmission is successful (or it turns itself off).
I am 100% sure your transmission attempts fail, because the bus is not set up correctly.
Check with a scope, and check the transmit and receive error counters (TEC, REC) in the CAN peripheral after each transmission attempt.
After a defined number of errors, the device goes first into passive mode, and then into "bus-off" mode.
2025-09-23 3:34 AM
I see your point. In my case, transmissions sometimes succeed, but not always. Could you help me pinpoint what part of the setup I should correct first?
2025-09-23 4:11 AM
What is your second device on the bus ?
CAN does not work with only one node. A successful transmission requires the acknowledge from another participant.
This could be a CAN dongle for a PC, if you configure it correctly (proper baudrate, and not in listen-only mode).
Check the physical signal, you could use a scope for that.
But if you need to deal with CAN more than once, get a PC CAN dongle (with appropriate software). I suppose the cheapest variant is a Raspberry Pi with a CAN shield and open source tools : https://github.com/ajouatom/canbus-tools
And you can monitor the success (or failure) of a transmission attempt in the debugger.
The TEC and REC counters are visible in the CAN register interface. If they go up after each transmission attempt, something is wrong.
If you have another STM32 board as second CAN device, you could connect the CAN signals (CAN_Tx, CAN_Rx and GND) directly, bypassing the transceivers. Rx/Tx would have to be crossed, then.
The usualy precautions for such direct connections between different boards apply ...
2025-09-23 8:43 AM - edited 2025-09-23 8:51 AM
Hello,
I tested your project with a little modification and there is no issue. I just connected another CAN node which is a NUCLEO-F767 board (CAN2.0) + a transceiver, and the latter is receiving the CAN frames from STM32H745I-DISCO without issues.
These are the frames send each 100ms:
This screenshot spots one frame:
A screenshot for IAR of the receiving CAN frame (F767 side) showing the Rx content changing in live (only data 0 and data 7 are changing):
Attached the projects that I used for the test.
Now, I'm pretty sure it's not a software issue and you have a hardware issue. Either with the transceiver or the wiring or something else. Maybe you swapped CAN_H and CAN_L? need to check.
Hope that helps.
2025-09-24 5:51 PM
What are you use to receive the data? The can bus analyzer? if in this case you can check the voltage of it, because i find that it will not receive data in many case when the voltage is lower than 5V.